2012-06-08 10 views
9

Mam trzy tabele:JOIN i GROUP_CONCAT z trzech tabel

users:  sports:   user_sports: 

id | name  id | name   id_user | id_sport | pref 
---+-------- ---+------------ --------+----------+------ 
1 | Peter  1 | Tennis    1 |  1 | 0 
2 | Alice  2 | Football   1 |  2 | 1 
3 | Bob  3 | Basketball   2 |  3 | 0 
             3 |  1 | 2 
             3 |  3 | 1 
             3 |  2 | 0 

tabeli user_sports linki users i sports o kolejności preferencji (pref).

muszę zrobić kwerendę, która zwraca to:

id | name | sport_ids | sport_names 
---+-------+-----------+---------------------------- 
1 | Peter | 1,2  | Tennis,Football 
2 | Alice | 3   | Basketball 
3 | Bob | 2,3,1  | Football,Basketball,Tennis 

Próbowałem z JOIN i GROUP_CONCAT ale mam dziwne wyniki.
Czy muszę wykonać zagnieżdżone zapytanie?
Jakieś pomysły?

+2

czy mógłbyś opublikować swoją rutynę group_concat, która nie działała? Wydaje się dokładnie to, czego potrzebujesz (zobacz tę stronę: http://stackoverflow.com/questions/276927/can-i-concatenate-multiple-mysql-rows-into-one-field), więc może być pomocne zobacz queryt o określić, jak poszło nie tak. – user158017

Odpowiedz

24

jej nie szczególnie trudne.

  1. Dołącz do trzech tabel za pomocą klauzuli JOIN.
  2. Używaj GROUP_CONCAT na polach, które Cię interesują.
  3. Nie zapomnij o klauzuli GROUP BY na polach nie jesteś złączenie lub weird things will happen


SELECT u.id, 
     u.Name, 
     Group_concat(us.id_sport order by pref) sport_ids, 
     Group_concat(s.name order by pref)  sport_names 
FROM users u 
     LEFT JOIN User_Sports us 
       ON u.id = us.id_user 
     LEFT JOIN sports s 
       ON US.id_sport = s.id 
GROUP BY u.id, 
      u.Name 

DEMO

Aktualizacja LEFT JOIN dla użytkownika, który nie ma ries w User_Sports jak na komentarze

+0

Amazing! +1 dla sqlfiddle – Peter

+1

Dlaczego połączenie wewnętrzne zamiast połączenia lewe? i pojedyncza "grupa po" wydaje się wystarczająca: http://sqlfiddle.com/#!2/4d402/9 – Peter

+0

Wewnętrzne połączenia zwykle działają lepiej niż lewe łączenia, więc zaczynam od tego. Czy interesują Cię użytkownicy, którzy nie istnieją w sports_users? –

3

myślę, że to tylko prosty dołączyć i agregacji:

select u.id, u.name, group_concat(s.name order by pref separator ',') 
from user_sports us join 
    users u 
    on us.id_user = u.id join 
    sports s 
    on us.id_sport = s.id 
group by u.id, u.name