Select
Jedním z klíčových příkazů jazyka SQL je příkaz SELECT sloužící k dotazování nad relacemi (tabulkami) uloženými v relačním databázovém systému. Příkaz SELECT ma celou řadu použití, která lze navzájem kombinovat. V příkladech na tomto cvičení budeme využívat tyto tabulky a data.
SELECT jako projekce
Nejjednodušší tvar má příkaz SELECT v případě relační operace projekce:
SELECT sloupec1, ..., sloupecN FROM tabulka;
V případě, že chceme vybrat všechny sloupce, je možné místo výčtu sloupců použít symbol *.
SELECT jmeno, vek FROM zamestnanci; SELECT * FROM zamestnanci;
Obecně výsledek operace SELECT nemusí být relace, výsledná tabulka může obsahovat duplicity. K odstranění duplicit slouží klíčové slovo DISTINCT psané hned za příkaz SELECT.
SELECT funkce FROM zamestnanci; SELECT DISTINCT funkce FROM zamestnanci;
SELECT jako rozšíření
Příkaz SELECT lze použít i k vytvoření nového sloupce, typicky na základě jiného sloupce či jiných sloupců. Ve výčtu sloupců lze použít libovolný výraz jazyka SQL eventuálně doplněného název nového sloupce. Takový SELECT má následující tvar:
SELECT vyraz1 AS nazev-sloupce1, ..., vyrazN AS nazev-sloupceN FROM tabulka;
SELECT jmeno, plat * 12 * 0.19 AS dan FROM zamestnanci;
Kličové slovo AS je možné vypustit. Všimněte si, že se takto dají jednotlivé sloupce i přejmenovávat.
SELECT jako selekce
Typickou operací kterou SELECT provádí je operace selekce, tzn. SELECT vrací jen řádky splňující danou podmínku. K tomu slouží klíčové slovo WHERE následované danou podmínkou.
SELECT * FROM zamestnanci WHERE funkce = 'Manager'; SELECT jmeno, plat FROM zamestnanci WHERE plat > 40000;
SELECT a agregace hodnot
SQL umožňuje hodnoty v jednotlivých řádcích agregovat, tj. vytvařet sumy, průměr, najít nejmenší nebo největší hodnotu, atd. Slouží k tomu agregační funkce:
MIN(vyraz)
-- vrací nejmenší hodnotu daného výrazu pro všechny řádkyMAX(vyraz)
-- vrací nevětší hodnotu daného výrazu pro všechny řádkySUM(vyraz)
-- vrací sumu všech hodnot daného výrazu pro všechny řádkyAVG(vyraz)
-- vrací průměr všech hodnot daného výrazu pro všechny řádkyCOUNT(vyraz)
-- vrací počet řádků, pro které daný výraz není NULLCOUNT(DISTINCT vyraz)
-- vrací počet řádků, pro které má daný výraz unikátní hodnotu a není NULLCOUNT(*)
-- vrací počet všech řádků
SELECT COUNT(*) AS pocet, MIN(plat) AS nejmensi_plat, AVG(uvazek) AS prumerny_uvazek FROM zamestnanci;
V tomto případě se provede agregace přes všechny řádky tabulky. To nemusí být vždy žádoucí a v řadě situací je potřeba agregovat podle zadaného klíče, v našem případě na základě hodnot v daných sloupcích. Příkladem takové situace je výpočet průměrné mzdy dle profese. Příkaz SELECT za tímto účelem má klíčové slovo GROUP BY následované seznamem sloupců, podle kterých má proběhnout agregace.
SELECT funkce, AVG(plat) FROM zamestnanci GROUP BY funkce; SELECT funkce, (vek / 10) * 10 AS vek_trida, MIN(plat) FROM zamestnanci GROUP BY funkce, vek_trida;
Při použití GROUP BY je možné, aby se za SELECT objevily jen výrazy použité v GROUP BY, výrazy obsahující agregační funkci nebo konstantní výrazy. Jinak se jedná o chybný dotaz.
Pokud se spolu s GROUP BY použije WHERE, je nejdříve aplikováno WHERE a až poté GROUP BY.
SELECT funkce, MIN(plat) AS min_plat FROM zamestnanci WHERE vek > 30 GROUP BY funkce;
Pokud je potřeba provést selekci nad agregovanými daty, slouží k tomu klíčové slovo HAVING.
SELECT funkce, MIN(plat) AS min_plat FROM zamestnanci GROUP BY funkce HAVING MIN(plat) > 10000;
SELECT a nerelační operace
Vedle relačních operací, hlavně z praktických důvodů, podporuje SQL i několik operací, které nemají oporu v relační algebře. Jednou z těchto operací je seřazení řádků ve výsledné tabulce. K seřazení slouží klíčové slovo ORDER BY následované seznamem sloupců podle, kterých má být seřazení provedeno. Za každý sloupec je možné přidat jeětě klíčové slovo ASC nebo DESC, jestli se májí hodnoty řadist sestupně nebo vzestupně. Pokud se žádné z těchto klíčových slov nevyskytne, předpokládá se vzestupné řazení.
SELECT * FROM zamestnanci ORDER BY jmeno, vek; SELECT * FROM zamestnanci ORDER BY plat DESC, jmeno;
Někdy je praktické omezit počet řádků v tabulce na určitý počet. K tomu slouží klíčové slovo LIMIT následované požadovaným počtem řádků.
SELECT * FROM zamestnanci ORDER BY vek LIMIT 2;
S omezením na určitý počet řádků ještě velice úzce souvisí klíčové slovo OFFSET, kterým lze určit od kolikáteho řádku (vzhledem k danému setřídění) mají být výsledky vráceny.
SELECT * FROM zamestnanci ORDER BY vek OFFSET 0; -- operace bez efektu SELECT * FROM zamestnanci ORDER BY vek OFFSET 1; -- z vysledku bude vyrazen prvni radek (nejmladsi pracovnik)
Je nutné zdůraznit, že LIMIT a OFFSET je možné použít pouze ve spojení s ORDER BY, které určuje seřazení řádků v tabulce. Pokud použijete LIMIT a OFFSET bez setřídění, výsledky dotazů mohou být nekonzistentní, protože jednotlivé řádky budou zvoleny nedeterministicky.
Pořadí jednotlivých operací
- pro každý řádek jsou vyhodnoceny výrazy (část hned za select)
- jsou vybrány řádky splňující podmínku WHERE
- dojde k agregaci hodnot pomocí GROUP BY
- jsou vybrány řádky splňující podmínku HAVING
- řádky jsou setřídeny podle ORDER BY
- jsou odfiltrovany řadky podle OFFSET
- je vybrán počet řádků daný zapomocí LIMIT
Na hodnoty vytvořené v SELECTu pomocí klíčového slova AS lze odkazovat z klauzulí GROUP BY a ORDER BY, ale není možné na ně odkazovat z WHERE a HAVING.
Množinové operace
Nad relacemi (tabulkami) můžeme provádět běžné množinové operace -- zejména se jedná o operace sjednocení, průniku rozdílu. Tyto operace spojují dva selecty následovně:
select1 UNION select2; select1 EXCEPT select2; select1 INTERSECT select2;
Všechny tyto operace implicitně odstraňují duplicitní řádky, pokud jsou duplicitní řádky potřeba, lze to vynutit doplněním klíčového slova ALL za danou operácí, tj. UNION ALL, EXCEPT ALL, INTERSECT ALL.
SELECT jmeno, vek FROM zamestnanci INTERSECT SELECT jmeno, vek FROM akcionari; -- seznam vsech zamestnancu, kteri jsou i akcionari SELECT jmeno, vek FROM zamestnanci EXCEPT SELECT jmeno, vek FROM akcionari; -- seznam vsech zamestnancu, kteri nejsou akcionari SELECT jmeno, vek FROM zamestnanci UNION SELECT jmeno, vek FROM akcionari; -- seznam vsech zamestancu i akcionaru SELECT jmeno, vek FROM zamestnanci UNION ALL SELECT jmeno, vek FROM akcionari; -- predchozi operace bez odstraneni duplicit
S použitím dat, zejména tabulky "country", která představuje (mírně zastaralé) informace o jednotlivých zemích světa, zjistěte následující informace:
- seznam všech kontinentů (bez duplicit)
- země, kde je státní zřízení republika
- počet všech zemí v tabulce
- počet obyvatel na km2 v každé zemi
- počet všech zemí v tabulce, kde je státní zřízení republika
- počet zemí na každém kontinentu
- velikost populace na každém kontinentě
- seznam vládců a počet zemí, ve kterých působí, setříděný podle počtu zemí sestupně
- vládce, kteří působí minimálně na dvou světových kontinentech
- vládce, kteří působí v Severní Americe nebo Evropě
- vládce, kteří působí současně v Severní Americe i Evropě
- vládce, kteří působí v Severní Americe, ale nepůsobí v Evropě
- co je největší evropská země dle rozlohy
- co je nejlidnatější region
- seznam všech vládců, kteří vládnou alespoň 100 000 000 obyvatel
- průměrný hrubý národní produkt (gnp) zemí podle regionu, které získaly nezávislost po roce 1950.