ARCHIV |
|||||
Software (10844)
Distribuce (131)
Skripty (697)
Menu
Diskuze
Informace
|
MySQL (26) - PoddotazyJak je to s těmi poddotazy v MySQL? Umí je nebo neumí? Minule jsem poprvé v tomto seriálu použil techniku, které se v odborné terminologii říká poddotaz. K poddotazům se váže poměrně oblíbený mýtus, a to sice ten, že je MySQL neumí. Tábor zastánců MySQL pak tvrdil, že poddotazy se dají při programování obejít, tábor odpůrců této databáze se zase naopak nechal slyšet, že to nejde a že MySQL je tím pádem naprosto nepoužitelná databáze. Dnes si ukážeme, jak je to doopravdy - co poddotazy jsou, k čemu slouží a jak je v MySQL efektivně používat.
Poddotaz je když...Termínem "poddotaz" je v SQL míněn platný "vnitřní" dotaz, který je součástí nějakého většího, "vnějšího" dotazu. Anglicky se označuje pojmem subquery, a můžeme rovněž slýchat označení vnořený dotaz. Zavzpomínáme-li na minulý díl, byl tam uveden tento poddotaz (v textu příkazu SQL jsem jej označil červeně). select oddeleni,
avg(plat) from pracovnik group by oddeleni having avg(plat)>(select avg(plat) from pracovnik);
Jak vlastně vzniklo tvrzení, že MySQL nepodporuje poddotazy? Obyčejná databáze skutečně poddotazy nepodporuje, tak tomu skutečně dřív bývalo, že ani MySQL poddotazy neměla. Ale pak se pár chytrých hlav dalo dohromady a řekli: Dost! A není náhodou, že těch pár chytrých hlav se sešlo v MySQL! Víte, co to znamená? To znamená, že jsme zase o krok před nimi! Takže teď vážně: MySQL podporuje poddotazy od verze 4.1 (což je podle některých správců "poměrně nedávno" a tuto verzi na svých systémech ještě nemusejí mít). Pro některé čtenáře to tedy bude spíše pohled do budoucnosti, než že by mohli poddotazy hned začít využívat. Dřívější verze MySQL (což zahrnuje řady 4.0 a všechny "trojkové") práci s poddotazy v plném slova smyslu skutečně neuměly. Poddotazy mají některé výhody, o nichž byste měli vědět (a díky nimž se používají). Mezi nejvýznamnější z nich patří:
Každá mince má dvě strany, a proto i poddotazy mají svoje nevýhody. Podotýkám, že tyto nevýhody se týkají hlavně špatně napsaných poddotazů, ale měli byste o nich vědět i v případě, že se chystáte psát dobré poddotazy.
Použití poddotazůBETWEEN a INTypické použití poddotazů je ve spojení s predikáty BETWEEN a IN. Ty byly již zmíněny v díle o filtrování dat. Zejména predikát IN je častým "terčem" poddotazů. Funguje to následovně: nejprve připomenu příklad z dílu o filtrování dat: select * from lidi where
mesto in ('Praha', 'Brno', 'Ostrava');
Všimněte si, že v tomto příkladu žádný poddotaz není a že hodnoty měst jsou zadány "natvrdo". Pokud bychom seznam měst měli uložen v samostatné tabulce, můžeme dotaz přepsat na: select * from lidi where
mesto in (select mesto from mesta);
Výhoda je jasná - jestliže se změní tabulka měst, druhý dotaz bude i nadále fungovat. Ten první by se ale musel po každé změně seznamu měst přepsat. V poddotazu můžeme používat prakticky všechny věci, které jsme se naučili u příkazu SELECT. Nic nám tedy nebrání vybrat jen lidi z měst nad 100000 obyvatel: select * from lidi where
mesto in (select mesto from mesta where obyvatel > 100000);
Jednu věc byste ale vědět měli - poddotaz použitý v souvislosti s predikátem IN musí vracet jen jeden sloupec. Takže, následující syntaxe je špatná, protože poddotaz vrací dva sloupce a nebohý hlavní dotaz netuší, který z nich má pro porovnání použít: select * from lidi where
mesto in (select mesto, poloha from mesta);
Poddotazy lze používat mnoha dalšími způsoby. V souvislosti s tím mě napadá, že je třeba zmínit se o speciálním operátoru - EXISTS. Poddotazy a EXISTSEXISTS funguje tak, že vrátí logickou hodnotu TRUE, pokud následující poddotaz obsahuje nějaké řádky. Pokud poddotaz žádné řádky nevrátí, EXISTS vrací FALSE. Vše bude asi nejlepší osvětlit na nějakém příkladu. Dejme tomu, že chceme vybrat všechna města, v nichž máme nějaké záznamy o obyvatelích: select * from mesta
where exists (select * from lidi where lidi.mesto=mesta.mesto);
Česky řečeno vrátí tento dotaz jen taková města, v nichž máme nějaké obyvatele. Na tomto typu poddotazu si můžete všimnout zajímavé věci - a to sice že poddotaz se "odvolává" na data v hlavím dotazu. To je možné. Ve skutečnosti je to pro funkci EXISTS naprosto typické. Poddotazům tohoto typu se říká korelační (anglicky correlated). Jak jsme v příkladech viděli, poddotaz může být v klauzuli HAVING a v klauzuli WHERE. Ve skutečnosti může být v příkazu prakticky kdekoli. Poddotaz může být dokonce i v jiném poddotazu! S poddotazy se budeme v dalších dílech seriálu sektávat průběžně, takže se s nejobvyklejšími konstrukcemi poddotazů ještě seznámíte. Poddotazy versus spojeníV souvislosti s poddotazy byste měli vědět, že některé z nich lze přepsat na spojení. Spojení bývá obecně rychlejší. Následující dva dotazy jsou tedy funkčně totožné, jeden však používá poddotaz a druhý spojení. select * from lidi where
mesto in (select mesto from mesta);
V dobách, kdy MySQL nepodporovala poddotazy byl přepis na spojení jedinou možností, jak se s podobnými úlohami vypořádat. Nezapomeňme však, že některé poddotazy na spojení zkrátka přepsat nejdou, a tudíž je lze smysluplně provést jen na verzích MySQL 4.1 a novějších. Pěkný rozbor této problematiky je v manuálu k MySQL.
Související články
Předchozí Celou kategorii (seriál) Další
MySQL (1) - pestrý svět databází
MySQL (2) - Instalujeme databázi MySQL MYSQL (3) Instalujeme MySQL podruhé MySQL (4) - něco terminologie MySQL (5) - tajuplné SQL MySQL (6) - Ukládáme řetězce MySQL (7) - hrátky s čísly MySQL (8) - Ukládání datumů MySQL (9) - Další datové typy MySQL (10) - tvorba databáze. Základy DDL MySQL (11) - vytváříme tabulky MySQL (12) - tipy k tvorbě tabulek MySQL (13) - Vkládáme data MySQL (14) - Upravujeme data MySQL (15) - Odstraňujeme data MySQL (16) - Tipy a triky k manipulaci s daty MySQL (17) - vybíráme data MySQL (18) - Filtrujeme data MySQL (19) - Řadíme data MySQL (20) - spojení více tabulek MySQL (21) - klauzule JOIN MySQL (22) - tipy a triky ke spojování tabulek MySQL (23) - relace 1:N a N:N MySQL (24) - Seskupujeme záznamy MySQL (25) - hrátky se seskupenými záznamy MySQL (27) - Složitější dotazy MySQL (28) - Dotazy pro pokročilé MySQL (29) - Vracení nejvyšších záznamů MySQL (30) - průběžné součty MySQL (31) - Indexy MySQL (32) - ještě k indexům MySQL (33) - Příkaz UNION MySQL (34) - větvení kódu a pivotní tabulky MySQL (35) - vestavěné funkce MySQL (36) - Regulární výrazy MySQL (37) - použití fulltextového vyhledávání MySQL (38) - Fulltext a praxe MySQL (39) - typy tabulek v MySQL MySQL (40) - další typy tabulek MySQL (41) - Transakce MySQL (42) - ještě k transakcím MySQL (43) - Uložené procedury MySQL (44) - parametry uložených procedur MySQL (45) - větvení kódu uložených procedur MySQL (46) - Triggery MySQL (47) - Triggery a praxe MySQL (48) - UDF MySQL (49) - pohledy MySQL (50) - Pohledy podruhé MySQL (51) - Metadata MySQL (52) - A co zálohování? MySQL (53) - SELECT INTO OUTFILE MySQL (54) - zálohování MySQL z webu MySQL (55) - zálohování MySQL z pohledu správce MySQL (56) - Obnova zálohovaných dat MySQL (57) - Ach, ta čeština MySQL (58) - čeština v praxi MySQL (59) - české řazení MySQL (60) - řádkový klient MySQL (61) - Oprávnění MySQL (62) - Oprávnění podruhé MySQL (63) - jemné nastavení práv MySQL (64) - nad dotazy čtenářů MySQL (65) - Ladíme server MySQL (66) - Ještě k ladění serveru MySQL - (67) MySQL (68) - Závěr MySQL (69) - Prepared Statements Předchozí Celou kategorii (seriál) Další
|
Vyhledávání software
Vyhledávání článků
28.11.2018 23:56 /František Kučera 12.11.2018 21:28 /Redakce Linuxsoft.cz 6.11.2018 2:04 /František Kučera 4.10.2018 21:30 /Ondřej Čečák 18.9.2018 23:30 /František Kučera 9.9.2018 14:15 /Redakce Linuxsoft.cz 12.8.2018 16:58 /František Kučera 16.7.2018 1:05 /František Kučera
Poslední diskuze
31.7.2023 14:13 /
Linda Graham 30.11.2022 9:32 /
Kyle McDermott 13.12.2018 10:57 /
Jan Mareš 2.12.2018 23:56 /
František Kučera 5.10.2018 17:12 /
Jakub Kuljovsky | |||
ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze |