Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Sortowanie użytkowników wg danych z dwóch tabel
Forum PHP.pl > Forum > Przedszkole
robertzet
Witam, mam następujacy problem.
Mam dwie tabele - uzytkownicy (w której przechowywane jest id, nazwa oraz kontrolka czy użytkownik może dostawać pochwały i nagany) oraz wyniki (w której przechowywane są id użytkownika oraz kontrolki - czy użytkownik otrzymał pochwałę czy naganę). Każda informacja o każdej pochwale lub naganie znajduje się w osobnym rekordzie.

tabela uzytkownicy
user_id, nazwa, uwzgledniaj
1, user1, 1
2, user2, 0
3, user3, 1
4, user4, 1

tabela wyniki
user_id, pochwala, nagana
1, 1, 0
1, 0, 1
1, 1, 0
4, 1, 0
3, 0, 1
4, 0, 1

Na podstawie tych dwóch tabel chciałbym otrzymać coś takiego:
user1: 2
user4: 0
user3: -1

Czyli zliczyć różnicę pochwał i nagan każdego użytkownika (który może pochwały i nagany otrzymywać) i posortować użytkowników wg tych danych malejąco.
Niestety nie wiem jak to zrobić.
Proszę o pomoc.

Pozdrawiam,
Robert Zetakowski
nospor
slowa kluczowe, ktore są niezbedne przy tej operacji:
LEFT JOIN
GROUP BY
SUM
robertzet
Czy na pewno LEFT JOIN to odpowiednie złączenie dla tego zapytania?
Jest możliwe wykonanie tego wszystkiego w jednym zapytaniu MySQL?
phpion
Cytat(robertzet @ 12.09.2013, 11:18:15 ) *
Czy na pewno LEFT JOIN to odpowiednie złączenie dla tego zapytania?

Tak. Zwykły JOIN pominąłby użytkowników bez pochwał/nagan.

Cytat(robertzet @ 12.09.2013, 11:18:15 ) *
Jest możliwe wykonanie tego wszystkiego w jednym zapytaniu MySQL?

Tak. Kluczowe zagadnienia podał Ci ~nospor. Od siebie dodam, że sumować musisz SUM(pochwala - nagana).
mmmmmmm
LEFT jest akurat tu niepotrzebny.
Da się to wykonać jednym zapytaniem. Np. takim:
  1. SELECT u.nazwa, Sum(w.pochwala-w.nagana) razem FROM uzytkownicy u JOIN wyniki w ON u.user_id=w.user_id GROUP BY 1 ORDER BY 2 DESC

EDIT: 2 DESC
Zwykły JOIN pokaże tylko użytkowników, którzy dostali pochwałę lub naganę.
phpion
Cytat(mmmmmmm @ 12.09.2013, 11:24:37 ) *
LEFT jest akurat tu niepotrzebny.

Racja, nie zwróciłem uwagi, że na wyjściu ~robertzet pomija user2, który nie ma żadnej pochwały/nagany.

PS: Mogłeś zostawić przyjemność złożenia zapytania autorowi, a nie podawać gotowe rozwiązanie na tacy.
PS2: Skoro mają być tylko użytkownicy z pochwałami/naganami to chyba wydajniej byłoby pobierać dane z wyniki i joinować użytkowników.
robertzet
Dziękuję serdecznie za pomoc.

Pozdrawiam.
mmmmmmm
Cytat(phpion @ 12.09.2013, 11:27:09 ) *
PS: Mogłeś zostawić przyjemność złożenia zapytania autorowi, a nie podawać gotowe rozwiązanie na tacy.

Racja. Święte słowa...
Cytat(phpion @ 12.09.2013, 11:27:09 ) *
PS2: Skoro mają być tylko użytkownicy z pochwałami/naganami to chyba wydajniej byłoby pobierać dane z wyniki i joinować użytkowników.

A tego nie kumam... Chodzi o kolejność tabel, czy o co?
robertzet
Witam,
niestety mam kolejny problem. Rozbudowałem bazę danych o dwie kolejne tabele - uwagi i wiadomości. W tabelach tych znajduje się pole user_id oraz treść uwagi/wiadomości o użytkowniku.

tabela wyniki
user_id, pochwala, nagana
1, 1, 0
1, 1, 0
1, 1, 0
3, 0, 1
3, 1, 0
3, 1, 0
3, 1, 0

tabela uwagi
user_id, uwaga
1, lorem ipsum
3, abc
1, qwerty
3, qwerty

tabela wiadomosci
user_id, wiadomosc
1, lorem ipsum
3, abc
1, qwerty
3, qwerty
3, qwerty
3, qwerty
3, qwerty

Moje zapytanie wygląda następująco:

  1. SELECT u.`user_id`, SUM(w.`pochwala`-w.`nagana`), COUNT(g.`user_id`), COUNT(m.`user_id`)
  2. FROM `uzytkownicy` u
  3. LEFT JOIN `wyniki` w ON u.`user_id` = w.`user_id`
  4. LEFT JOIN `uwagi` g ON u.`user_id` = g.`user_id`
  5. LEFT JOIN `wiadomosci` m ON u.`user_id` = m.`user_id`
  6. GROUP BY 1


Chciałbym wyciągnąć z tabel dane o pochwałach, ilości uwag o użytkowniku oraz ilości wiadomości o użytkowniku, a więc oczekiwany przeze mnie rezultat powinien wyglądać następująco:

user_id: współczynnik pochwał do nagan, ilość uwag, ilość wiadomości
1: 3, 2, 2
3: 2, 2, 5

Natomiast rezultat wygląda następująco:
1: 12, 12, 12
3: 20, 40, 40

Czy jest ktoś w stanie nakierować mnie, w czym tkwi problem?

Pozdrawiam.

EDIT Problem rozwiązany, może komuś się przyda:

  1. SELECT u.user_id, COALESCE(w.res, 0) res, COALESCE(g.nts, 0) nts, COALESCE(m.msg, 0) msg
  2. FROM uzytkownicy u
  3. LEFT JOIN
  4. (
  5. SELECT user_id, SUM(pochwala - nagana) res
  6. FROM wyniki
  7. GROUP BY user_id
  8. ) w ON u.user_id = w.user_id
  9. LEFT JOIN
  10. (
  11. SELECT user_id, COUNT(*) nts
  12. FROM uwagi
  13. GROUP BY user_id
  14. ) g ON u.user_id = g.user_id
  15. LEFT JOIN
  16. (
  17. SELECT user_id, COUNT(*) msg
  18. FROM wiadomosci
  19. GROUP BY user_id
  20. ) m ON u.user_id = m.user_id
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.