Spojení a skupiny
Spojení a GROUP BY se dobře doplňují: spojení dá data z několika tabulek do řádků a GROUP BY je shrne. Kolik kusů her kterého žánru si zákazníci objednali? Počty kusů jsou v tabulce polozky, žánry v tabulce hry:
SELECT h.zanr, SUM(p.pocet) AS kusy
FROM polozky AS p
JOIN hry AS h ON p.hra_id = h.id
GROUP BY h.zanr
ORDER BY kusy DESC, h.zanr;| zanr | kusy |
|---|---|
| Akční | 8 |
| RPG | 7 |
| Strategie | 7 |
| … | … |
Spojení dá řádek pro každou položku, s žánrem její hry. GROUP BY pak vytvoří skupinu pro každý žánr a SUM v každé skupině sečte počty kusů.
S penězi je to stejné. Položka vynesla počet kusů krát cenu, kterou zákazník zaplatil za jeden kus: p.pocet * p.cena. Ne h.cena: to je cena v katalogu, a ve slevě zákazníci platí méně. Peníze, které skupina vynesla, tedy její tržba, jsou pak SUM(p.pocet * p.cena): SUM spočítá výraz pro každý řádek skupiny a výsledky sečte.
Když seskupujete podle něčeho, co má jméno, třeba podle zákazníka nebo hry, seskupte podle jeho id a jméno přidejte do GROUP BY také: GROUP BY z.id, z.jmeno. Dva zákazníci se můžou jmenovat stejně a samotné GROUP BY z.jmeno by je dalo do jedné skupiny, jako by to byl jeden člověk. Díky jménu v GROUP BY ho můžete ukázat v SELECT: každá skupina má jedno id, a tedy i jedno jméno. Kolik recenzí napsal který zákazník a kolik hvězdiček v průměru dává?
SELECT z.jmeno, COUNT(*) AS pocet_recenzi, ROUND(AVG(r.hvezdicky), 1) AS prumer
FROM recenze AS r
JOIN zakaznici AS z ON r.zakaznik_id = z.id
GROUP BY z.id, z.jmeno
ORDER BY pocet_recenzi DESC, z.jmeno;| jmeno | pocet_recenzi | prumer |
|---|---|---|
| Eva Novotná | 5 | 4.4 |
| Adéla Králová | 2 | 3.5 |
| Anna Kučerová | 2 | 3.5 |
| … | … | … |
Vrácená objednávka nevynesla nic, takže tržba má počítat jen zaplacené objednávky. Stav je v tabulce objednavky: připojte i ji a zaplacené objednávky vyberte pomocí WHERE. WHERE se provádí před GROUP BY, takže řádky vrácených objednávek zmizí dřív, než se cokoli sčítá. HAVING pak vybírá skupiny, jak znáte z minulé lekce.
Typická chyba: SUM(pocet * cena) bez aliasů. Když je v dotazu tabulka hry, je cena nejednoznačná a dostanete chybu. SUM(p.pocet * h.cena) je ještě horší: proběhne, ale sečte ceny z katalogu a sleva z tržby zmizí.
Jak psát:
Pokyny
Ukažte tržbu každé hry ze zaplacených objednávek: nazev a tržbu jako trzba. Potřebujete tři tabulky: polozky, objednavky (kvůli stavu) a hry. Hry seřaďte podle tržby od nejvyšší, potom podle názvu:
| nazev | trzba |
|---|---|
| Knight's Oath | 4797 |
| Dragon Forge | 3996 |
| Goal Rush | 2598 |
| Ice Hockey Pro | 2398 |
| Turbo Karts | 2397 |
| Zombie Town | 2097 |
| … | … |
Pod něj ukažte, kolik zaplacených objednávek zadal který zákazník: jmeno a počet jako pocet_objednavek, seřazené podle pocet_objednavek od nejvyššího, potom podle jmeno:
| jmeno | pocet_objednavek |
|---|---|
| Eva Novotná | 4 |
| Tereza Svobodová | 4 |
| Jakub Dvořák | 3 |
| Lukáš Procházka | 3 |
| Adéla Králová | 2 |
| … | … |
A kteří zákazníci utratili v zaplacených objednávkách víc než 3 000 Kč? Ukažte jmeno a utracenou částku jako utraceno, jen u zákazníků, kteří utratili víc než 3 000 Kč, seřazené podle utraceno od nejvyšší, potom podle jmeno:
| jmeno | utraceno |
|---|---|
| Eva Novotná | 5224 |
| Tereza Svobodová | 3924 |
| Jakub Dvořák | 3896 |
| Lukáš Procházka | 3894 |
Začněte programovat zdarma
6/12