Pojmenované poddotazy: WITH

Poddotazy v části FROM umějí dotaz pěkně znepřehlednit. Musíte ho číst zevnitř ven a s každým dalším poddotazem se zanořuje hlouběji. WITH (s) vám dovolí napsat poddotaz napřed, pojmenovat ho a pak jeho jméno používat jako tabulku:

WITH soucty AS (
    SELECT objednavka_id, SUM(pocet * cena) AS celkem
    FROM polozky
    GROUP BY objednavka_id
)
SELECT ROUND(AVG(celkem), 2) AS prumerna_objednavka
FROM soucty;
prumerna_objednavka
1093.17

Je to průměrná objednávka z minulého cvičení, jenže teď se čte shora dolů: nejdřív se spočítají součty objednávek, které dostanou jméno soucty, a pak jejich průměr. Části WITH nazev AS (dotaz) se říká CTE (z anglického common table expression, tedy „společný tabulkový výraz“). Patří k dotazu, který za ní následuje: dohromady tvoří jeden příkaz s jedním středníkem na konci a název soucty platí jen uvnitř tohoto příkazu.

Pojmenovaný dotaz můžete použít i víckrát. Největší objednávka je ta, jejíž součet se rovná největšímu součtu:

WITH soucty AS (
    SELECT objednavka_id, SUM(pocet * cena) AS celkem
    FROM polozky
    GROUP BY objednavka_id
)
SELECT objednavka_id, celkem
FROM soucty
WHERE celkem = (SELECT MAX(celkem) FROM soucty);
objednavka_idcelkem
112198

Bez WITH byste dotaz, který počítá součty, museli napsat dvakrát: jednou do části FROM a jednou do poddotazu v části WHERE.

WITH může pojmenovat i několik dotazů, oddělených čárkami; slovo WITH se píše jen na začátku. Každý z nich může používat ty před sebou. Tady zaplacene vybere zaplacené objednávky, soucty_zaplacenych spočítá jejich součty a hlavní dotaz je sečte:

WITH zaplacene AS (
    SELECT *
    FROM objednavky
    WHERE stav = 'zaplaceno'
),
soucty_zaplacenych AS (
    SELECT p.objednavka_id, SUM(p.pocet * p.cena) AS celkem
    FROM polozky AS p
    JOIN zaplacene AS z ON z.id = p.objednavka_id
    GROUP BY p.objednavka_id
)
SELECT COUNT(*) AS pocet_zaplacenych, SUM(celkem) AS trzba
FROM soucty_zaplacenych;
pocet_zaplacenychtrzba
2831247

Typické chyby: čárka za posledním pojmenovaným dotazem, těsně před hlavním SELECT (near "SELECT": syntax error), a středník za jeho uzavírací závorkou, který ukončí příkaz dřív, než hlavní dotaz vůbec začal (near ";": syntax error).

Pokyny

Dotaz v editoru najde měsíc s nejvyšší tržbou, jenže tržbu každého měsíce počítá dvakrát, ve dvou stejných poddotazech. Přepište ho pomocí WITH: dotaz, který počítá tržby po měsících, pojmenujte mesice a jméno použijte na obou místech. Výsledek zůstane stejný:

mesictrzba
2024-124194

Pod něj ukažte pro každého zákazníka, který zadal objednávku a napsal recenzi, jeho jméno, počet jeho objednávek jako pocet_objednavek a počet jeho recenzí jako pocet_recenzi. Objednávky každého zákazníka spočítejte v jednom pojmenovaném dotazu, recenze ve druhém a pak oba spojte s tabulkou zakaznici. (Kdybyste k zákazníkům připojili rovnou objednavky i recenze, řádky by se znásobily: každá objednávka s každou recenzí.) Seřaďte podle jména:

jmenopocet_objednavekpocet_recenzi
Adéla Králová22
Anna Kučerová22
Eva Novotná45
………

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

7/8