Seznam z poddotazu: IN

Ve 3. lekci jste používali IN se seznamem hodnot: WHERE id IN (1, 3, 5). Seznam ale nemusíte psát ručně, může ho vytvořit poddotaz. Které hry mají aspoň jednu recenzi s pěti hvězdičkami? ID těchto her najdete v tabulce recenze:

SELECT hra_id FROM recenze WHERE hvezdicky = 5;
hra_id
1
1
3
6
…

Dejte tento dotaz do závorek za IN a vnější dotaz najde názvy her:

SELECT nazev
FROM hry
WHERE id IN (SELECT hra_id FROM recenze WHERE hvezdicky = 5)
ORDER BY nazev;
nazev
Cube Logic
Dragon Forge
Knight's Oath
Moon Farm
Star Pilots
Turbo Karts
Zombie Town

Poddotaz se provede jako první a vrátí seznam: 1, 1, 3, 6, 7, 10, 14, 15. Pak IN u každé hry zkontroluje, jestli je její id v seznamu. Dragon Forge (1) je v seznamu dvakrát, ale na tom nezáleží: IN se ptá jen na to, jestli tam hodnota je, takže každá hra je ve výsledku nejvýš jednou.

Na rozdíl od poddotazů z minulého cvičení smí poddotaz za IN vrátit libovolný počet řádků, klidně i žádný (pak IN nic nenajde). Musí ale vracet právě jeden sloupec, protože IN porovnává jednu hodnotu se seznamem hodnot:

SELECT nazev
FROM hry
WHERE id IN (SELECT hra_id, hvezdicky FROM recenze);
Error on line 1: sub-select returns 2 columns - expected 1

Zpráva říká, že poddotaz vrací dva sloupce, ale čekal se jeden. Stejné hry byste našli i spojením tabulek:

SELECT h.nazev
FROM hry AS h
JOIN recenze AS r ON r.hra_id = h.id
WHERE r.hvezdicky = 5
ORDER BY h.nazev;
nazev
Cube Logic
Dragon Forge
Dragon Forge
Knight's Oath
Moon Farm
Star Pilots
Turbo Karts
Zombie Town

Spojení vytvoří řádek pro každou odpovídající recenzi, takže Dragon Forge se dvěma pětihvězdičkovými recenzemi je tu dvakrát a potřebovali byste DISTINCT. Co tedy použít? Když ve výsledku potřebujete sloupce druhé tabulky, třeba hvězdičky nebo komentář, potřebujete spojení. Když druhá tabulka jen rozhoduje, které řádky si nechat, IN s poddotazem říká přesně to, co myslíte: „hry, jejichž ID je mezi těmito“.

Typická chyba: = místo IN. WHERE id = (SELECT hra_id FROM recenze WHERE hvezdicky = 5) není v SQLite chyba, ale jak jste viděli v minulém cvičení, vezme jen první hodnotu ze seznamu, takže najde jen Dragon Forge.

Pokyny

Dotaz v editoru najde hry, které si už někdo koupil, pomocí spojení a DISTINCT. Přepište ho bez spojení: ukažte názvy her, jejichž id je v seznamu hodnot hra_id z tabulky polozky. Použijte IN s poddotazem. Výsledek zůstane stejný:

nazev
Bakery Story
Castle Siege
Cube Logic
…

Pod něj ukažte jméno a město zákazníků, kteří zadali objednávku v prosinci, v kterémkoli roce. ID těchto zákazníků najde poddotaz v tabulce objednavky; měsíc z data získáte pomocí strftime('%m', datum). Seřaďte podle jména:

jmenomesto
Eva NovotnáPraha
Lukáš ProcházkaOstrava
Tereza SvobodováPraha
Vojtěch PokornýPlzeň

Poddotaz může obsahovat další poddotaz. Ukažte jméno a e-mail zákazníků, kteří napsali recenzi hry Dragon Forge: poddotaz najde ID autorů recenzí v tabulce recenze a uvnitř něj další poddotaz najde ID hry podle jejího názvu. Seřaďte podle jména:

jmenoemail
Anna Kučerováanna.kucerova@mail.cz
Eva Novotnáeva.novotna@mail.cz
Jakub Dvořákjakub.d@mail.cz
Matěj Němecmatej.nemec@mail.cz

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

2/8