Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ocena skryptu] wspólni znajomi
Forum PHP.pl > Inne > Oceny
sebekzosw
Witam! Mam pewien skrypt:

  1. $znajomy = 2;
  2. $ja = 1;
  3.  
  4. $znajomi1 = array();
  5. $znajomi1_query = mysql_query("SELECT `u`.`user_id` FROM `friends` AS `f` LEFT JOIN `users` AS `u` ON `u`.`user_id` = ( IF( `f`.`user1` =".$znajomy.", `f`.`user2` , `f`.`user1` ) ) WHERE (`user1` =".$znajomy." OR `user2` =".$znajomy.") AND `status` =1;");
  6. while($znajomi1_row = mysql_fetch_assoc($znajomi1_query)) $znajomi1[] = $znajomi1_row['user_id'];
  7.  
  8. $znajomi2 = array();
  9. $znajomi2_query = mysql_query("SELECT `u`.`user_id` FROM `friends` AS `f` LEFT JOIN `users` AS `u` ON `u`.`user_id` = ( IF( `f`.`user1` =".$ja.", `f`.`user2` , `f`.`user1` ) ) WHERE (`user1` =".$ja." OR `user2` =".$ja.") AND `status` =1;");
  10. while($znajomi2_row = mysql_fetch_assoc($znajomi2_query)) $znajomi2[] = $znajomi2_row['user_id'];
  11.  
  12. print_r(array_intersect($znajomi1, $znajomi2));


Który porównuje mi moich i innej osoby znajomych. Oto wyniki:

Kod
moi znajomi:
Array
(
    [0] => 1996
    [1] => 1
    [2] => 24306
    [3] => 12639
    [4] => 5057
    [5] => 1757
)

znajomi kogoś:
Array
(
    [0] => 2
    [1] => 1757
)

wspólni znajomi:
Array
(
    [5] => 1757
)


Dodatkowo zamieszczam zrzut tabeli friends:
  1. CREATE TABLE `friends` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `user1` int(11) NOT NULL COMMENT 'id usera 1 - zapraszajacego',
  4. `user2` int(11) NOT NULL COMMENT 'id usera 2 - zaproszonego',
  5. `status` int(1) NOT NULL DEFAULT '0' COMMENT '0 - niezaakceptowane, 1 - zaakceptowane',
  6. `data` int(11) NOT NULL,
  7. PRIMARY KEY (`id`),
  8. KEY `id` (`id`,`user1`,`user2`,`status`,`data`)
  9. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=2 ;


proszę o ocenę i poprawki smile.gif
phpion
Ocena? Pała, siadaj.

Takie rzeczy możesz robić (i powinieneś!) na poziomie samej bazy danych. Co jeśli chciałbym do tego dołożyć np. imiona i nazwiska wspólnych znajomych? Możesz walnąć kolejne zapytanie (czyli mamy już 3). Możesz też w pierwszym lub drugim zapytaniu dołączyć dane użytkowników (ale przy np. 1000 znajomych pierwszego użytkownika i 0 wspólnych pobierasz zbędnie 1000 rekordów i zapisujesz je do tablicy).

Niestety MySQL nie wspiera INTERSECT. Jednak w Google znajdziesz rozwiązania okrężne. Podaję pierwsze z brzegu:
Cytat
Doing an INTERSECT

An INTERSECT is simply an inner join where we compare the tuples of one table with those of the other, and select those that appear in both while weeding out duplicates. So

  1. SELECT member_id, name FROM a
  2. INTERSECT
  3. SELECT member_id, name FROM b


can simply be rewritten to

  1. SELECT a.member_id, a.name
  2. FROM a INNER JOIN b
  3. USING (member_id, name)

Źródło: http://www.bitbybit.dk/carsten/blog/?p=71

PS: Twój index też jest z dupy. Po pierwsze: id masz kluczem głównym więc po co pakować go w dodatkowy index (szczególnie na pierwszy miejscu). Po drugie: sprawdzałeś czy taka kombinacja (wszystkich pól!) sprawi, że index zostanie użyty? Nie sprawdzałeś, bo nie zostanie użyty. Poza tym: po co Ci kolumna id? Postaw klucz główny na dwóch kolumnach (user1 i user2). Patrząc dalej na strukturę tabeli: pole status powinno być typu ENUM z określoną listą wartości, polu data lepiej nadać typ DATETIME lub TIMESTAMP ("od tego są one, od tego one są, od tego są, od tego są one").
sebekzosw
nie mam pojęcia jak to zapytanie całe połączyć, może jakaś pomoc?
Czyluk
http://funkcje.net/nsc/4/2867/0/38/page.html
Kwerendy są bardzo przydatne, radzę się ich nauczyć smile.gif
sebekzosw
nie potrafię tego wymyślić...

znalazłem takie coś: http://forums.digitalpoint.com/showthread.php?t=590030 ale nie działają te zapytania ... ;/

zna ktoś rozwiązanie?

Kod
SET @user = 2; @znajomy = 921;

SELECT
    IF(`f1`.`user1` = @user, `f1`.`user2`, `f1`.`user1`) AS `user_id`
FROM
    `friends` AS `f1`
WHERE
(`f1`.`user1` = @user OR `f1`.`user2` = @user) AND
`f1`.`status` = 1
AND
    IF(`f1`.`user1` = @user, `f1`.`user2`, `f1`.`user1`)
    IN (
        SELECT
            IF(`f2`.`user1` = @user, `f2`.`user2`, `f2`.`user1`)
        FROM
            `friends` AS `f2`
        WHERE
        (`f2`.`user1` = @znajomy OR `f2`.`user2` = @znajomy) AND
        `f2`.`status` = 1
    )
HAVING
    `user_id` != @znajomy;


co myślicie o tym zapytaniu?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.