Pořadí částí dotazu
Teď už znáte všechny části dotazu. Píšou se v tomto pořadí a kteroukoli z nich kromě SELECT můžete vynechat:
SELECT …
FROM …
WHERE …
GROUP BY …
HAVING …
ORDER BY …
LIMIT …;Databáze je ale neprovádí v pořadí, v jakém je píšete, nýbrž v pořadí, v jakém je potřebuje:
FROM– vezme řádky tabulky.WHERE– nechá řádky, které splňují jeho podmínku.GROUP BY– rozdělí řádky do skupin a agregační funkce spočítají hodnoty pro každou skupinu.HAVING– nechá skupiny, které splňují jeho podmínku.SELECT– spočítá sloupce výsledku a pojmenuje je podleAS(aDISTINCTodstraní opakující se řádky).ORDER BY– seřadí řádky výsledku.LIMIT– nechá jen prvních pár řádků (po přeskočeníOFFSETřádků).
Toto pořadí vysvětluje mnohé z toho, co jste v této lekci viděli. WHERE se provádí před GROUP BY, a proto v něm nemůžou být agregační funkce: skupiny ještě neexistují. HAVING se provádí po GROUP BY, a proto v něm být můžou. A ORDER BY se provádí po SELECT, takže už zná názvy, které jste sloupcům dali: proto funguje ORDER BY pocet_her DESC.
Podle stejné logiky nemůžou WHERE, GROUP BY a HAVING aliasy používat, protože se provádějí dřív, než je SELECT vytvoří. Ve většině databází, třeba v PostgreSQL, MySQL, SQL Serveru nebo Oracle, je alias ve WHERE chyba a některé ho nedovolí ani v GROUP BY nebo HAVING. SQLite je shovívavé: když najde název, který není sloupcem tabulky, podívá se mezi aliasy, takže tohle v SQLite funguje, dokonce i ve WHERE:
SELECT nazev, cena * 2 AS dva_kusy
FROM hry
WHERE dva_kusy > 3000;| nazev | dva_kusy |
|---|---|
| Knight's Oath | 3198 |
Ale nespoléhejte na to. Alias, který se jmenuje jako skutečný sloupec, znamená ten sloupec; alias agregační funkce nejde ve WHERE použít ani v SQLite, protože skupiny ještě neexistují; a v jiné databázi takový dotaz přestane fungovat. Ve WHERE, GROUP BY a HAVING pište samotný výraz (WHERE cena * 2 > 3000, HAVING COUNT(*) >= 3) a aliasy používejte v ORDER BY.
Ve druhém dotazu tohoto cvičení konečně vynecháte vrácené objednávky. To, že byla objednávka vrácená, je zapsané v tabulce objednavky, ale položky jsou v tabulce polozky, a abyste mohli použít obě tabulky v jednom dotazu, musíte je spojit. To je téma příští lekce. Do té doby si poradíte s ID vrácených objednávek: SELECT id FROM objednavky WHERE stav = 'vraceno'; zjistí, že jsou to 7 a 18, a WHERE objednavka_id NOT IN (7, 18) pak jejich položky vynechá. Je to ale jen nouzové řešení: seznam ID napsaný ručně přestane platit, jakmile zákazník vrátí další objednávku, kdežto dotaz se spojením tabulek najde vrácené objednávky sám.
Jak psát:
Pokyny
Kolega napsal dotaz, který má ukázat zákazníky s aspoň 2 objednávkami v roce 2025, ale skončí chybou. Opravte ho tak, aby ukázal tohle:
| zakaznik_id | objednavky_2025 |
|---|---|
| 3 | 2 |
| 11 | 2 |
| 13 | 2 |
Pod něj napište dotaz, který použije všechny části. Které hry vydělaly nejvíc v objednávkách, které nebyly vrácené? Z tabulky polozky vynechte položky vrácených objednávek 7 a 18 (pomocí NOT IN, jak je popsáno výše), seskupte řádky podle hry a ukažte hra_id, počet prodaných kusů (součet pocet) ve sloupci kusy a součet pocet * cena ve sloupci trzba. Nechte jen hry, kterých se prodaly aspoň 3 kusy, seřaďte je od nejvyšší tržby a ukažte první 3:
| hra_id | kusy | trzba |
|---|---|---|
| 15 | 3 | 4797 |
| 1 | 4 | 3996 |
| 14 | 3 | 2397 |
Začněte programovat zdarma
10/10