SQL – pokročilá práce s tabulkami a daty
V dnešním díle si ukážeme využití vnořování SQL dotazů do příkazů pro manipulaci s daty (INSERT, UPDATE, DELETE). Druhou část pak budu věnovat dalším typům spojování tabulek, které nám rozšíří další možnosti konstrukce pokročilých SQL dotazů.
Ještě než se pustíte dále, můžete si přečíst slibované řešení příkladů zadaných na konci minulého dílu.
Řešení příkladů
a) Vypište seznam knih, které napsal pan Horáček samostatně (tj. ne jako spoluautor):
|
b) Vypište seznam knih, které byly v devadesátých letech vydány alespoň třemi různými nakladatelstvími:
|
c) Následující SELECT dává odpověď na dotaz: „vypište seznam všech autorů, kteří nenapsali žádnou knihu samostatně“.
|
Pokročilé vkládání dat
Nejprve se podívejme na příkaz INSERT, který jsme probírali ve 4. díle. Někdy v databázovém systému vytvoříme časem novou tabulku, a tu budeme chtít naplnit daty, která můžeme získat z jiných tabulek. Syntaxe příkazu INSERT má tedy dva tvary:
|
Syntaxi toho prvního již známe, podívejme se blíže na druhou variantu. Data do nové tabulky naplníme daty z jiných tabulek, které nám vrátí vnořený SELECT. Důležité je, že struktura sloupců, které nám vrací vnořený dotaz, musí být stejná, jako je struktura sloupců nové tabulky, do které data chceme vkládat. Strukturou rozumím stejný počet vzájemně si odpovídajících sloupců (tzn. odpovídají si typy sloupců). Uveďme si jednoduchý příklad. Na vysokou školu se nám hlásili uchazeči o studium. Máme tabulku UCHAZEČI vytvořenou následujícím příkazem:
|
A dále v systému již existuje tabulka STUDENTI evidující již studující studenty na naší škole. Předpokládejme, že tabulka STUDENTI má podobnou strukturu jako UCHAZEČI, tj. obsahuje sloupce ID, JMÉNO a PŘÍJMENÍ. Nyní si představme, že skončilo přijímací řízení a že kritérium pro přijetí je získání alespoň 200 bodů. Z uchazečů uděláme studenty následujícím příkazem
|
za předpokladu, že máme nějakým způsobem ošetřeno, že nám nedojde ke kolizi ID jednotlivých lidí. Kdybychom kritérium pro přijetí zvolili „přijati jsou všichni, kteří dosáhli nadprůmerného zisku bodů“, příkaz INSERT by vypadal následovně:
|
Tím jsem jen chtěl poukázat na to, že vnořený příkaz SELECT nemusí být jenom jednoduchý, ale může to být libovolně strukturovaný dotaz. Důležité je, aby vracel stejnou strukturu sloupců.
Aktualizace dat
U příkazů UPDATE a DELETE nebude nic zvlášť nového. Použití těchto příkazů se nám rozšiřuje jen o možnost aplikování vnořených dotazů v části WHERE (restrikce). Kdybychom všem, kteří mají podprůměrný plat, chtěli přidat 500 Kč k základnímu platu a 100 Kč k osobnímu ohodnocení, zapsali bychom to následovně:
|
V průběhu vykonávání příkazu UPDATE se nám průměrný plat nebude měnit, protože vnořený příkaz se v tomto případě vyhodnotí jen jednou.
Spojování tabulek pomocí intervalu
Co se týká spojování tabulek, tak v 6. díle jsme se seznámili jejich přirozeným spojením. Standard SQL definuje další možná spojení tabulek. Jak už jste mohli vysledovat, v příkladech c) ve cvičení jsem použil spojení tabulky se sebou samou. Neděje se tak příliš často, ale někdy je to docela užitečné. Využijeme to v těch případech, kdy potřebujeme „znovu nahlédnout“ do téže tabulky a něco zjistit, např. jestli k danému KNIHA_ID existuje ještě jeden záznam, apod. Spojení tabulky se sebou samou je přirozeným spojením v klasickém slova smyslu a realizuje se úplně stejným postupem, jako přirozené spojení dvou různých tabulek.
U přirozeného spojení jste si mohli všimnout, že bylo realizováno na základě rovnosti dvou hodnot ve vybraných sloupcích (primární a cizí klíč). Tabulky můžeme spojovat i na základě nerovnosti. Tomu se v SQL říká spojení tabulek pomocí intervalu. Uveďme si nyní příklad, kde využijeme intervalového spojení tabulek.
Příklad
Představme si, že máme nějakou univerzitu. Budeme si vést číselník pracovišť. Nejvyšší pracoviště bude mít číslo 1. Univerzita se nám bude dělit na fakulty. Každá fakulta k tomu číslu 1 přidá další cifru. Např. pedagogicka fakulta by měla číslo 12. V rámci každé fakulty budou určitá pracoviště. Každé pracoviště do číselníku k předchozím cifrám přidá další. Např. studijní oddělení pedagogické fakulty bude mít číslo 127.
A řekněme, že si v systému povedeme tabulku PRAVOMOCI, která bude obsahovat lidi a jejich pravomoci nad určitými pracovišti. Pravomoc bude vyjádřena jako interval od kterého čísla do kterého čísla pracoviště. Nechť naplnění tabulek vypadá následovně:
PRACOVIŠTĚ PRAVOMOCI ————————- ———————– ID NÁZEV PLNÉ_JMÉNO P_OD P_DO 1 Masarykova univerzita Jan Novák 1 1 12 Pedagogická fakulta Petr Nový 11 15 13 Fakulta informatiky David Dvořák 121 129 127 studijní oddělení 137 studijní oddělení 121 děkanát 122 ekonomické oddělení
Podívejme se na tabulku PRAVOMOCI. Z ní zjistíme, že např. Petr Nový má pravomoce nad prvními pěti fakultami, David Dvořák na pracoviště v rámci pedagogické fakulty. Budeme-li chtít seznam názvů všech pracovišť, na kterým má pravomoce Petr Nový, zapíšeme dotaz následovně:
|
Znovu opakuji, že toto je úplně jiný přístup ke spojování tabulek. Někdy je výhodnější, neboť ušetří místo na disku. Kdybychom uvedený příklad chtěli řešit pomocí klasického přirozeného spojení tabulek, tabulky, které by nesly tytéž informace, by vypadaly takto:
PRACOVIŠTĚ LIDÉ PRAVOMOCI ————————- ————— ——— ID NÁZEV ID PLNÉ_JMÉNO OS_ID PR_ID 1 Masarykova univerzita 1 Jan Novák 1 1 12 Pedagogická fakulta 2 Petr Nový 2 11 13 Fakulta informatiky 3 David Dvořák 2 12 127 studijní oddělení 2 13 137 studijní oddělení 2 14 121 děkanát 2 15 122 ekonomické oddělení 3 121 … 3 129
Všimněte si, že jednotlivá PR_ID pro každou osobu jdou v řadě za sebou, tj. jednotlivá PR_ID tvoří interval, proto bylo výhodnější využít původní varianty s intervalovým spojením tabulek. V momentě, kdy bychom např. Petrovi Novému odepřeli pravomoce na pracoviště 13, tak bychom museli použít klasický přístup ke spojování tabulek. Uvedený dotaz bychom v tomto případě zapsali ekvivalentně takto:
|
Intervalové spojení lze chápat jako rozšíření, v podstatě se mu dá při návrzích systémů úplně vyhnout.
Spojení tabulek bez omezení
Další možností je spojení dvou tabulek bez omezení – kartézský součin tabulek. V části WHERE nedefinujeme žádnou podmínku pro sloupce. Výsledná tabulka obsahuje spojené řádky každý s každým. Např. má-li první tabulka 10 záznamů, druhá 20, tak výsledná po spojení bude mít 200 záznamů. Nepoužívá se moc často, ale někdy se to může hodit.
Příklad
Jednoduchý příklad bych mohl demonstrovat na hodu dvěma kostkami. Zajímá nás tabulka všech možných hodů bílou a modrou kostkou. Pro každý možný vypsaný hod, budeme chtít znát součet ok hozených na obou kostkách dohromady. Budeme mít dvě tabulky BÍLÁ a MODRÁ, které budou obsahovat následující údaje:
BÍLÁ MODRÁ —- —– ČÍSLO TEXT ČÍSLO TEXT 1 jedna 1 one 2 dva 2 two 3 tři 3 three 4 čtyři 4 four 5 pět 5 five 6 šest 6 six
Dotaz na seznam všech hodů včetně součtu hozených ok bude vypadat následovně:
|
Tento dotaz nám vrátí celkem 36 řádků, kde se postupně vystřídají všechny kombinace hodů dvěma kostkami.
V příštím díle se podíváme na další použití spojených tabulek a tvorbu pohledů (tzv. VIEW).
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
-
Jak lze snadno upravovat soubory v PDF?
14. září 2023 -
Thunderbolt 4 vs. OCuLink: Přišel čas na upgrade?
27. května 2024 -
Aktualizujete svoji .NET webovou aplikaci? Může se hodit app_offline.htm
10. července 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