Dotaz na výsledek dotazu
Na konci první lekce jste četli, že výsledek dotazu je také tabulka. To znamená, že se na něj můžete ptát dalším dotazem: dejte poddotaz do FROM, tam, kde by byl název tabulky.
Kolik stojí průměrná objednávka? Tabulka polozky má řádek pro každou hru v objednávce, takže nejdřív potřebujete součet každé objednávky:
SELECT objednavka_id, SUM(pocet * cena) AS celkem
FROM polozky
GROUP BY objednavka_id;| objednavka_id | celkem |
|---|---|
| 1 | 628 |
| 2 | 899 |
| 3 | 1048 |
| … | … |
Pak průměr těchto součtů. AVG(SUM(pocet * cena)) nefunguje, protože agregační funkce nejde vnořit jednu do druhé: skončí chybou misuse of aggregate function SUM(). Součty ale můžete spočítat v poddotazu a jejich průměr ve vnějším dotazu:
SELECT ROUND(AVG(celkem), 2) AS prumerna_objednavka
FROM (
SELECT objednavka_id, SUM(pocet * cena) AS celkem
FROM polozky
GROUP BY objednavka_id
) AS soucty;| prumerna_objednavka |
|---|
| 1093.17 |
Poddotaz se provede jako první a vytvoří dočasnou tabulku o 30 řádcích, jeden pro každou objednávku, se sloupci objednavka_id a celkem. Vnější dotaz s ní zachází jako s každou jinou tabulkou: může filtrovat její řádky, seskupovat je, počítat s nimi. O tabulce polozky neví nic, vidí jen sloupce poddotazu, pod názvy, které jim poddotaz dal. Proto potřebuje každý vypočítaný sloupec poddotazu alias.
Za uzavírací závorkou následuje název tabulky, tady AS soucty. SQLite ho nevyžaduje, většina jiných databází ale ano, a potřebujete ho vždycky, když se na sloupce poddotazu odkazujete, třeba ve spojení. Ano, i poddotaz můžete spojit s dalšími tabulkami. Tohle jsou tři největší objednávky i s datem z tabulky objednavky:
SELECT o.id, o.datum, s.celkem
FROM (
SELECT objednavka_id, SUM(pocet * cena) AS celkem
FROM polozky
GROUP BY objednavka_id
) AS s
JOIN objednavky AS o ON o.id = s.objednavka_id
ORDER BY s.celkem DESC, o.id
LIMIT 3;| id | datum | celkem |
|---|---|---|
| 11 | 2024-09-30 | 2198 |
| 14 | 2024-12-20 | 1998 |
| 5 | 2024-04-02 | 1698 |
Typická chyba: použít sloupec, který poddotaz nevrací. Vnější dotaz vidí jen objednavka_id a celkem, takže cena nebo pocet v něm skončí chybou no such column.
Jak psát:
Pokyny
Kolik zákazníků zadalo jednu objednávku, kolik dvě a tak dál? V poddotazu spočítejte objednávky každého zákazníka v tabulce objednavky jako pocet_objednavek. Ve vnějším dotazu seskupte jeho řádky podle pocet_objednavek a spočítejte je jako pocet_zakazniku. (Zákazníci, kteří si nic neobjednali, v tabulce objednavky nejsou, takže se nepočítají.) Seřaďte podle sloupce pocet_objednavek:
| pocet_objednavek | pocet_zakazniku |
|---|---|
| 1 | 1 |
| 2 | 6 |
| 3 | 3 |
| 4 | 2 |
Pod něj ukažte hry, které jsou dražší než průměrná cena jejich žánru: název, žánr, cenu a průměrnou cenu žánru zaokrouhlenou na jedno desetinné místo jako prumer_zanru. Průměr každého žánru spočítejte v poddotazu a spojte ho s tabulkou hry podle žánru. Seřaďte podle žánru, pak podle názvu:
| nazev | zanr | cena | prumer_zanru |
|---|---|---|---|
| Mystery Manor | Adventura | 649 | 515.7 |
| Robot Rebellion | Akční | 999 | 836.5 |
| Star Pilots | Akční | 899 | 836.5 |
| … | … | … | … |
Začněte programovat zdarma
6/8