Myślę, że najprostszym podejściem do tego, co próbujesz zrobić, jest użycie skorelowanych podzapytań.
Tak więc pierwszy przykład tuż poniżej zwraca wyniki, których szukasz . Możesz go łatwo zmodyfikować, aby wykluczyć wiersze z zerowymi golami i asystami.
Używa wartości team_id w każdym podzapytaniu, ale możesz podać ją ze zmienną lub parametrem, jak pokazano, więc wystarczy określić wartość tylko raz:
set @team_id := 2;
select
p.id as player_id
, p.last_name
, (
select count(*)
from goals
where player_id = p.id
and team_id = @team_id
) as goals
, (
select count(*)
from assists
inner join goals on assists.goal_id = goals.id
where assists.player_id = p.id
and goals.team_id = @team_id
) as assists
from players p
Dla zespołu 1:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 1 | Gretzky | 2 | 1 |
| 2 | Lemieux | 0 | 0 |
| 3 | Messier | 1 | 1 |
+----+-----------+-------+---------+
Dla zespołu 2:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 1 | Gretzky | 0 | 0 |
| 2 | Lemieux | 1 | 0 |
| 3 | Messier | 0 | 0 |
+----+-----------+-------+---------+
Dla zespołu 3:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 1 | Gretzky | 0 | 1 |
| 2 | Lemieux | 0 | 0 |
| 3 | Messier | 1 | 0 |
+----+-----------+-------+---------+
Epilog
Z perspektywy próby zrobienia tego za pomocą mniejszej liczby podzapytań i/lub zapytań agregujących, przy pierwszej próbie pojawia się kilka problemów.
Jednym z problemów jest to, że zapytanie prawdopodobnie nie będzie działać poprawnie, jeśli nie uwzględnisz wszystkich pól w group by
nawet jeśli MySQL nie będzie na ciebie narzekał, tak jak (większość?) innych baz danych.
Ponadto, ponieważ rekordy zarówno w tabelach asyst, jak i graczy są tylko pośrednio powiązane z drużynami w tabeli bramek, trudno jest uzyskać niezależne zestawienie obu bramek i asyst za pomocą tylko jednego zapytania.
Jako ilustracja, inne wczesne odpowiedzi na to, w tym moje pierwsze szybkie ujęcie, miały kilka problemów:
-
Jeśli zawodnik miał asysty dla drużyny, ale nie miał żadnych bramek dla tej drużyny, zapytania nie mogły zwrócić żadnych wyników dla tej kombinacji zawodnika i drużyny. Wyniki były niekompletne.
-
Jeśli gracz miał cele dla drużyny, ale nie miał asyst dla tej drużyny, zapytania nadal zwracałyby dodatnią liczbę dla asyst, podczas gdy powinien był zwrócić zero. Wyniki były w rzeczywistości błędne, a nie tylko niekompletne .
Tuż poniżej znajduje się nieco bardziej poprawne, ale wciąż niekompletne rozwiązanie. Prawidłowo wskazuje, czy gracz nie ma asyst, chociaż zwraca null zamiast 0, co jest niefortunne.
Ale nadal jest to częściowe rozwiązanie, ponieważ jeśli zawodnik nie ma żadnych celów dla drużyny, nadal nie zobaczysz żadnych asyst dla tej kombinacji zawodnika i drużyny.
Wykorzystuje to podzapytanie jako wirtualną tabelę, która agreguje asysty na gracza i drużynę, a lewe sprzężenie zewnętrzne do podzapytania sprawia, że zwraca on wynik, jeśli są gole, ale nie ma asyst.
select
p.id as player_id
, p.last_name
, count(g.game_id) as goals
, a.assists
from players p
inner join goals g on p.id = g.player_id
left join (
select
assists.player_id
, goals.team_id
, count(assists.id) as assists
from assists
inner join goals on assists.goal_id = goals.id
group by player_id, team_id, assists.id
) a
on g.player_id = a.player_id and g.team_id = a.team_id
where g.team_id = 1
group by player_id, last_name, g.team_id
To zapytanie zwraca te wyniki:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 1 | Gretzky | 2 | 1 |
| 3 | Messier | 1 | 1 |
+----+-----------+-------+---------+
Uruchom to dla drużyny 2, a otrzymasz kolejne wyniki, wskazujące, że Lemieux nie ma żadnych asyst dla drużyny 2, ale nie zwraca żadnych wyników dla pozostałych dwóch graczy, którzy nie mają asyst i bramek dla drużyny 2:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 2 | Lemieux | 1 | null |
+----+-----------+-------+---------+
Na koniec uruchom go dla zespołu 3, a otrzymasz kolejne wyniki, wskazujące, że Messier nie ma żadnych asyst dla zespołu 3. Ale Gretzky'ego brakuje, mimo że ma asystę dla zespołu 3, ponieważ nie ma dowolne cele dla zespołu 3. Rozwiązanie nie jest więc kompletne:
+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
| 3 | Messier | 1 | null |
+----+-----------+-------+---------+