SQL – vnořené dotazy
Vnořené dotazy využijeme tam, kde potřebujeme získat nějaké informace na základě jiných údajů uložených v databázi. V tomto díle si povíme, jak nám mohou být vnořené dotazy užitečné. Zmíním se o zásadách, které musíme dodržovat při psaní vnořených dotazů. Řekneme si o základním jednoduchém vnořování a vnořování s využitím operátorů IN, ANY, SOME a ALL.
Použití vnořených dotazů
Vnořený dotaz není nic jiného, než příkaz SELECT vnořený do jiného příkazu SELECT. Vnořené dotazy využijeme tam, kde potřebujeme nejprve zjistit nějakou informaci a v závislosti na ní zjistit pak informace další. Typickým příkladem by mohl být následující dotaz. Vypište seznam všech zaměstnanců, kteří mají nadprůměrný plat. Pomocí klasických SQL dotazů, které zatím známe, tento výsledek obdržíme ve dvou krocích. Nejprve si zjistíme, jaký je průměrný plat ve firmě (použijeme agregační funkci AVG):
|
Tento dotaz nám vrátí např. číslo 15600. Toto číslo si zapamatujeme a použijeme jej v konstrukci následujícího dotazu:
|
Jistě uznáte, byť je tento příklad docela jednoduchý, že by někdy bylo pohodlnější, kdybychom oba kroky mohli spojit do jednoho, tj. napsali bychom jeden příkaz, který by nám potřebný seznam zaměstnanců vrátil.
Jednoduché vnořené dotazy
Za jednoduchý vnořený dotaz budeme považovat vnořený příkaz SELECT vracející nám jednu hodnotu. Můžeme psát restrikce s využitím právě té hodnoty, kterou nám vrátí vnořený SELECT. Vnořený příkaz se píše do závorek a v dotazu je uveden v části WHERE. Výše uvedený dotaz bychom zapsali následovně:
|
V restrikci výše uvedeného příkazu máme podmínku plat > vypočtená_hodnota. Vypočtená_hodnota se nám vyhodnotí vnořeným SELECTem na jednu hodnotu a máme tedy podmínku zapsanou v pořádku a dotaz je korektní. Pro úplnost uvádím, že vnořený SELECT se vyhodnotí pouze jednou, hodnotu si SQL server „zapamatuje“ a s ní pak porovnává všechny ostatní hodnoty v tabulce.
V jednoduchých vnořených dotazech (někdy nazýváme poddotazy) nám obdobným způsobem budou figurovat i další agregační funkce. V následujících příkladech, demonstrujících užití jednoduchých poddotazů se budu odkazovat na tabulky, které jsem si zadefinovali v 5. díle o jazyce SQL.
Příklady
Zjistěte název a cenu nejlevnější knihy.
|
Vypište jména všech autorů, kteří se podíleli při psaní nejdelší knihy (=s největším počtem stran)
|
Poddotazy vracející více hodnot
V předchozích příkladech jsme měli situaci, že vnořený dotaz nám vrátil jednu hodnotu (toto nám v podstatě zajistila agregační funkce). Někdy ale můžeme nechat vyhodnotit poddotaz, který nám vrátí více hodnot. Chceme např. dotaz, vracející nám názvy všech knih vydaných v týchž letech, jako díla Aloise Jiráska. Vnořený poddotaz nám zjistí množinu všech roků, ve kterých bylo kdy něco od Jiráska vydáno a pak vyhledáme všechny knihy vydané v těchto letech. Než uvedu zápis takového dotazu, zmíním se ještě o nových operátorech.
Operátory
Vnořování dotazů nám rozšiřuje klasickou množinu relačních operátorů o operátory další, které se aplikují z levé strany na sloupec a z pravé strany na vnořený dotaz vracející více hodnot. Mezi ně patří operátory IN, ANY (SOME), ALL.
Operátor IN slouží pro jednoduché porovnání, zdali se hodnota sloupce vlevo vyskytuje mezi hodnotami vrácených vnořeným dotazem. Kdybychom např. chtěli názvy knih vydané v letech 1997 až 2000, mohli bychom takový dotaz pomocí operátoru IN zapsat takto:
|
Výraz v závorce je množina všech hodnot, ve kterých se má daná hodnota hledat. Většinou neuvádíme výčet explicitně, ale vrací nám jej nějaký vnořený dotaz. V této chvíli si tedy lze uvést náš dotaz na názvy knih vydaných v týchž letech, jako díla Aloise Jiráska:
|
Všimněte si, že jsem ve vnořeném dotazu v části FROM použil aliasy pro názvy tabulek. To proto, že tytéž názvy se objevují i v nadřazeném SELECTu. Kdybyste v tomto příkladu aliasů nepoužili, chyba by to nebyla, dotaz by vrátil očekávaná data. Ale někdy (a uvidíme to v příštím díle) je použití aliasů nutné, neboť v některých případech bude SQL server potřebovat vědět, na kterou tabulku v restrikci vnořeného dotazu se odkazujeme – zdali na tu „lokální“ nebo na tu „globální“.
V případě dlouhých názvů některých tabulek je výhodou je v rámci dotazu nahradit kratšími názvy. Podotýkám, že aliasy tabulek se narozdíl od aliasů sloupců, neuvozují modifikátorem AS.
Použití operátorů ANY(SOME) a ALL ukazuje následující syntaxe:
|
Operátor ANY nebo SOME určují, že relace se vztahuje na alespoň jednu z hodnot, kterou vrátí vnořený dotaz, operátor ALL aplikuje relaci na všechny hodnoty vrácené poddotazem.
Příklad
Chceme seznam takových knih od Vítězslava Nezvala, jejichž výtisky nebyly nikdy dražší, než kterýkoliv výtisk díla Aloise Jiráska.
|
Výše uvedený dotaz můžeme přepsat použitím operátoru ANY v kombinaci s operátorem NOT (rozdíl bude jen v řádku, kde uvádíme sloupec CENA):
|
V příštím díle se budu věnovat pokročilým SQL dotazům, podrobně popíšu operátor EXISTS, který nám rozšíří vnořování dotazů o další možnosti. A dále se zmíním o využití vnořených dotazů při manipulaci s daty.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Co je to VRAM a jak ji navýšit bez drahého upgradu?
20. srpna 2024 -
Co je to DNSSEC, jak funguje a jak si ho nastavit?
14. srpna 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024