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:

  1. FROM – vezme řádky tabulky.
  2. WHERE – nechá řádky, které splňují jeho podmínku.
  3. GROUP BY – rozdělí řádky do skupin a agregační funkce spočítají hodnoty pro každou skupinu.
  4. HAVING – nechá skupiny, které splňují jeho podmínku.
  5. SELECT – spočítá sloupce výsledku a pojmenuje je podle AS (a DISTINCT odstraní opakující se řádky).
  6. ORDER BY – seřadí řádky výsledku.
  7. 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;
nazevdva_kusy
Knight's Oath3198

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.

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_idobjednavky_2025
32
112
132

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_idkusytrzba
1534797
143996
1432397

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

10/10