sql >> Databáze >  >> RDS >> Mysql

Problém se získáním správného počtu při připojení

Myslím, že nejpřímější přístup k tomu, co se pokoušíte udělat, je použít korelované dílčí dotazy.

Takže první příklad hned níže vrátí výsledky, které hledáte . Můžete jej snadno upravit tak, aby vyloučil řady s nulovými góly a asistencemi.

V každém dílčím dotazu používá hodnotu team_id, ale můžete ji dodat s proměnnou nebo parametrem, jak je znázorněno, takže hodnotu stačí zadat pouze jednou:

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

Pro tým 1:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  1 | Gretzky   |     2 |       1 |
|  2 | Lemieux   |     0 |       0 |
|  3 | Messier   |     1 |       1 |
+----+-----------+-------+---------+

Pro tým 2:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  1 | Gretzky   |     0 |       0 |
|  2 | Lemieux   |     1 |       0 |
|  3 | Messier   |     0 |       0 |
+----+-----------+-------+---------+

Pro tým 3:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  1 | Gretzky   |     0 |       1 |
|  2 | Lemieux   |     0 |       0 |
|  3 | Messier   |     1 |       0 |
+----+-----------+-------+---------+

Epilog

Z pohledu pokusu o to udělat s menším počtem dílčích dotazů a/nebo s agregovanými dotazy máte při prvním pokusu několik problémů.

Jedním problémem je, že váš dotaz pravděpodobně nebude fungovat správně, pokud nezahrnete všechna pole do group by klauzule, i když na vás MySQL nebude nadávat jako (většina?) jiných databází.

Také protože záznamy ve vašich tabulkách asistencí a hráčských tabulek souvisejí s týmy pouze nepřímo prostřednictvím tabulky gólů, je docela obtížné získat nezávislý souhrn pro góly a asistence pomocí jediného dotazu.

Pro ilustraci, jiné první odpovědi na to, včetně mého prvního rychlého pokusu o to, měly několik problémů:

  • Pokud měl hráč asistence pro tým, ale neměl pro tento tým žádné góly, dotazy nemohly vrátit žádné výsledky pro daného hráče a kombinaci týmu. Výsledky byly neúplné.

  • Pokud měl hráč góly pro tým, ale neměl pro tento tým žádné asistence, dotazy by stále vracely kladné číslo asistencí, i když by měly vrátit nulu. Výsledky byly ve skutečnosti chybné, nejen neúplné .

Níže je o něco správnější, ale stále neúplné řešení. Správně ukazuje, zda hráč nemá žádné asistence, i když vrací hodnotu null místo 0, což je nešťastné.

Ale stále je to částečné řešení, protože pokud hráč nemá žádné góly pro tým, stále neuvidíte žádné asistence pro daného hráče a kombinaci týmu.

Toto používá poddotaz jako virtuální tabulku, která agreguje asistence na hráče a tým, a levé vnější spojení s poddotazem je to, co umožňuje vrátit výsledek, pokud jsou góly, ale žádné asistence.

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

Tento dotaz vrací tyto výsledky:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  1 | Gretzky   |     2 |       1 |
|  3 | Messier   |     1 |       1 |
+----+-----------+-------+---------+

Spusťte to pro tým 2 a získáte tyto další výsledky, což znamená, že Lemieux nemá žádné asistence pro tým 2, ale nevrátí vůbec žádné výsledky pro další dva hráče, kteří nemají žádné asistence a žádné góly pro tým 2:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  2 | Lemieux   |     1 |    null |
+----+-----------+-------+---------+

Nakonec to spusťte pro tým 3 a získáte tyto další výsledky, což naznačuje, že Messier nemá žádné asistence pro tým 3. Ale Gretzky chybí, i když má asistenci pro tým 3, protože nemá jakékoli cíle pro tým 3. Řešení tedy není kompletní:

+----+-----------+-------+---------+
| id | last_name | Goals | Assists |
+----+-----------+-------+---------+
|  3 | Messier   |     1 |    null |
+----+-----------+-------+---------+



  1. 2 nejlepší záznamy MySQL na skupinu

  2. IO.FileNotFoundException v MySql.Data.dll:Nelze načíst System.Security.Permissions

  3. Použití Simple Membership Provider s mysql

  4. Jak získat aktuální datum a čas (bez časového pásma) v PostgreSQL