Počítání s LEFT JOIN
S LEFT JOIN můžete spočítat i věci, které nemají žádný protějšek. Kolik objednávek zadal který zákazník, včetně těch, kteří nezadali žádnou?
SELECT z.jmeno, COUNT(*) AS pocet_radku, COUNT(o.id) AS pocet_objednavek
FROM zakaznici AS z
LEFT JOIN objednavky AS o ON o.zakaznik_id = z.id
GROUP BY z.id, z.jmeno
ORDER BY pocet_objednavek, z.jmeno;| jmeno | pocet_radku | pocet_objednavek |
|---|---|---|
| Filip Beneš | 1 | 0 |
| Martin Zeman | 1 | 0 |
| Natálie Marková | 1 | 1 |
| Adéla Králová | 2 | 2 |
| … | … | … |
Podívejte se na Filipa Beneše: COUNT(*) říká 1, COUNT(o.id) říká 0. Proč? COUNT(*) počítá řádky a LEFT JOIN dal Filipovi jeden řádek, ten s hodnotami NULL ve sloupcích tabulky objednavky. COUNT(o.id) počítá jen hodnoty, které nejsou NULL (5. lekce), a v jediném Filipově řádku je o.id NULL. Proto říká 0, a to je správná odpověď. Natálie Marková má jednu skutečnou objednávku a v obou sloupcích 1.
Když tedy po LEFT JOIN počítáte protějšky, nepoužívejte COUNT(*). Počítejte sloupec pravé tabulky, který u skutečného protějšku nikdy není NULL, tedy stejný, jaký byste testovali pomocí IS NULL: její primární klíč, nebo sloupec s NOT NULL.
SUM, AVG, MIN a MAX hodnoty NULL také přeskakují a pro skupinu, ve které nejsou jiné hodnoty než NULL, vrátí NULL, ne 0. Útrata zákazníka bez objednávek by tak vyšla NULL. Když chcete 0, použijte COALESCE ze 4. lekce: COALESCE(SUM(p.pocet * p.cena), 0).
Typická chyba: počítání s obyčejným JOIN. Zákazníci bez objednávek zmizí ještě před GROUP BY, takže ve výsledku žádné nuly nejsou a nic vám neřekne, že někdo chybí.
Jak psát:
Pokyny
U každé hry ukažte, kolik má recenzí: nazev a počet jako pocet_recenzi. Hry bez recenze tam musí být s nulou. Řádky seřaďte podle pocet_recenzi, potom podle nazev:
| nazev | pocet_recenzi |
|---|---|
| Castle Siege | 0 |
| Lost Temple | 0 |
| Mystery Manor | 0 |
| Robot Rebellion | 0 |
| Bakery Story | 1 |
| … | … |
Pod něj ukažte, kolik kusů každé hry si zákazníci objednali, včetně vrácených objednávek: nazev a součet počtů kusů jako kusy. U her, které si nikdo neobjednal, musí být kusy 0, ne NULL. Řádky seřaďte podle kusy, potom podle nazev:
| nazev | kusy |
|---|---|
| Lost Temple | 0 |
| Mystery Manor | 0 |
| Robot Rebellion | 0 |
| Castle Siege | 1 |
| Goal Rush | 2 |
| Ice Hockey Pro | 2 |
| Ocean Deep | 2 |
| Star Pilots | 2 |
| … | … |
Začněte programovat zdarma
9/12