SQL - co jsou to ty agregace?

Druhý díl našeho seriálu byl věnován úvodu do příkazu SELECT. Slíbili jsme si, že se dnes podíváme na to, co jsou agregační funkce. Zkusíme si také vybrat data z více tabulek.
Druhý díl našeho seriálu byl věnován úvodu do příkazu SELECT. Slíbili jsme si, že se dnes podíváme na to, co jsou agregační funkce. Zkusíme si také vybrat data z více tabulek.

Pod pojmem agregační funkce si můžeme představit například funkci COUNT (ano, hádáte správně, vrátí počet záznamů) či funkci SUM. Zopakujme si zjednodušenou syntaxi příkazu SELECT:

SELECT [DISTINCT] položky FROM jméno_tabulky [WHERE podmínka_výběru] [GROUP BY položky, [HAVING podmínka_agregace]] [ORDER BY položky]

Standardně (v některých implementacích mohou být realizovány i některé další) je v SQL obsaženo pět agregačních funkcí - COUNT, SUM, MIN, MAX a AVG. Pro bližší vysvětlení rozšíříme naši tabulku z minulého dílu o položku (atribut) počet_dětí. Tabulka osoby tak bude mít následující podobu:

jméno příjmení rodné_číslo datum počet_dětí
Karel Smolný 580815/8777 3.12.1992 2
Marek Jurda 650404/8956 2.11.1992 3
Martin Pavlásek 720303/5511 28.3.1990 3
Pavel Jirásek 551212/7877 26.3.1989 2
Pavla Nováková 785308/4569 28.6.1997 5
Pavla Nováková 555111/3042 28.5.1990 1
Romana Bourková 745226/8820 3.5.1995 5

Význam jednotlivých agregačních funkcí je na první pohled patrný z jejich názvu. Na několika příkladech si ukažme, jak je můžeme použít.

SELECT MIN(počet_dětí), MAX (počet_dětí), AVG (počet_dětí) FROM osoby

dává výsledek:

MIN (počet_dětí) MAX (počet_dětí) AVG(počet_dětí)
1 5 3
SELECT COUNT(počet_dětí) FROM osoby WHERE počet_dětí> 2

dává výsledek (tedy kolik osob má více dětí než 2):

COUNT (počet_dětí)
4
Aź k tomuto místu se zdá, že vše je jasné a jednoduché. Problémy mohou nastat při používání klauzulí GROUP BY a HAVING. O první z nich lze říci, že nám vybrané řádky sdružuje do skupin podle zvolených položek. Druhá je pak podobná klauzuli WHERE, avšak s tím rozdílem, že podmínka je vztažena na celou skupinu, nikoli na záznam. GROUP BY tedy můžeme použít například ve chvíli, kdy potřebujeme rozdělit počet osob podle počtu jejich dětí:

SELECT počet_dětí, COUNT (počet_dětí) FROM osoby GROUP BY počet_dětí ORDER BY počet_dětí

dává výsledek:

počet_dětí COUNT(počet_dětí)
1 1
2 2
3 2
5 2

Pokud nás zajímá jen takový počet dětí, který je alespoň u dvou osob, je vhodný čas na využití klauzule HAVING:

SELECT počet_dětí, COUNT (počet_dětí) FROM osoby GROUP BY počet_dětí HAVING COUNT (počet_dětí)>1 ORDER BY počet_dětí

dává výsledek (všimněte si, že nám vypadl řádek s jedním dítětem):

počet_dětí COUNT(počet_dětí)
2 2
3 2
5 2

Možností, jak agregační funkce v SQL použít, je pochopitelně víc. Stejně tak je jejich dokonalé pochopení (a tedy i schopnost odpovídajícího využití) otázkou praktických zkušeností. Podstatné je si uvědomit, že jednotlivé klauzule příkazu SELECT lze mezi sebou kombinovat a takřka vždy tak získat odpověď na všechno, co se chceme dozvědět.

Dosud jsme pracovali pouze s jednou jedinou tabulkou. Jak postupovat, když potřebuji dvě tabulky spojit? V praktickém životě existují především dva požadavky na slučování dat z více (pro jednoduchost uvažujme dvě) tabulek. Prvním je získat podle klíčové položky, například podle rodného čísla, doplňující údaje o dané osobě. Těmi mohou být informace o předchozích zaměstnavatelích. Druhou možností je "sloučit" stejné (obsahující tytéž položky) tabulky či dva dotazy se shodnými položkami výběru. Například tehdy, máme-li tabulku zaměstnanců v podniku A i B a chceme získat seznam pracovníků obou dvou podniků. V prvním případě hovoříme o tzv. JOINu, ve druhém pak o UNIONu. Pro názornou ukázku si zaveďme další dvě tabulky - předchozích zaměstnavatelů a osob pracujících v jiné továrně (shodnou s nám již známou tabulkou osoby).

rodné_číslo předchozí_zaměstnavatel
580815/8777 České dráhy
580815/8777 FIMU
650404/8956 Computer Press
650404/8956 ČVUT
650404/8956 VUT
720303/5511 ČSAD Brno
720303/5511 MHD Brno
551212/7877 MHD Praha
785308/4569 MHD Praha
785308/4569 Slovenské dráhy
785308/4569 MHD Bratislava
555111/3042 ČVUT
745226/8820 VUT
745226/8820 Česká televize
Jméno příjmení rodné_číslo datum počet_dětí
David Mladý 770511/4577 1.11.1992 1
Emil Starý 880505/1155 2.10.1992 4
Jiří Nováček 780503/1425 28.4.1990 1
Karel Pavel 611110/1425 26.6.1991 5
Katka Silná 675309/4569 22.6.1995 1
Milena Ničivá 545212/4542 23.4.1992 2
Zdena Malá 715812/8820 4.11.1995 1

První typ si tedy ukážeme na dotazu, který by nám měl zodpovědět na otázku, které předchozí zaměstnavatele měly osoby uvedené v tabulce osobyA. Dobře si povšimněte omezující podmínky na stejná rodná čísla. Bez ní by výsledkem dotazu byl kartézský součin obou tabulek.

SELECT a.rodné_číslo, a.jméno, a.příjmení, b.předchozí_zaměstnavatel FROM osobyA a, předchozí_zaměstnavatelé b WHERE a.rodné_číslo= b.rodné_číslo

dává výsledek:

a.rodné_číslo a.jméno a.příjmení b.předchozí_zaměstnavatel
580815/8777 Karel Smolný České dráhy
580815/8777 Karel Smolný FIMU
650404/8956 Marek Jurda Computer Press
650404/8956 Marek Jurda ČVUT
650404/8956 Marek Jurda VUT
720303/5511 Martin Pavlásek ČSAD Brno
720303/5511 Martin Pavlásek MHD Brno
551212/7877 Pavel Jirásek MHD Praha
785308/4569 Pavla Nováková MHD Praha
785308/4569 Pavla Nováková Slovenské dráhy
785308/4569 Pavla Nováková MHD Bratislava
555111/3042 Pavla Nováková ČVUT
745226/8820 Romana Bourková VUT
745226/8820 Romana Bourková Česká televize

Tečková notace (a, b) nám určuje příslušnost jednotlivých položek ke konkrétní tabulce. Její používání je nutné tehdy, když není možné jednoznačně určit, z které tabulky chcete položku vybrat. V zájmu lepší přehlednosti by se však měla používat vždy.

Následující příklad nám ukazuje druhý typ dotazu nad více tabulkami. Podotýkám, že pro UNION je nutná shoda ve vybíraných položkách.

SELECT jméno,příjmení,rodné_číslo,datum FROM osobyA UNION SELECT jméno,příjmení,rodné_číslo,datum FROM osobyB

dává výsledek:

jméno příjmení rodné_číslo datum
Karel Smolný 580815/8777 3.12.1992
Marek Jurda 650404/8956 2.11 .1992
Martin Pavlásek 720303/5511 28.3.1990
Pavel Jirásek 551212/7877 26.3.1989
Pavla Nováková 785308/4569 28.6.1997
Pavla Nováková 555111/3042 28.5.1990
Romana Bourková 745226/8820 3.5.1995
David Mladý 770511/4577 1.11.1992
Emil Starý 880505/1155 2.10.1992
Jiří Nováček 780503/1425 28.4.1990
Karel Pavel 611110/1425 26.6.1991
Katka Silná 675309/4569 22.6.1995
Milena Ničivá 545212/4542 23.4.1992
Zdena Malá 715812/8820 4.11.1995

V tomto a předchozím díle jsme se zajímali pouze o to, jak data z tabulek "přečíst" a otázka jejich vkládání či změna zůstávala stranou. Možná jste už někdy slyšeli něco o příkazech INSERT a UPDATE. Pokud ne, nevadí - příště si jejich funkci podrobně vysvětlíme.

Předchozí díly
Nevíte si s SQL rady? Zeptejte se!
2. díl o SQL - začínáme s příkazem Select
Víte, co je SQL? Ne? Nevadí - dnes začínáme!
Diskuze (1) Další článek: Dokonáno jest – America Online koupila Netscape

Témata článku: Software, Programování, Order, Stejný dotaz, Položka, Slovenská televize, Zjednodušený příklad, From, Počet dětí, Dítě, MHD, Marko, Union, Dráha, Jednotlivý díl, SQL, Emily, Select, První jméno, První funkce

Určitě si přečtěte


Aktuální číslo časopisu Computer

Zachraňte nefunkční Windows

Jak nakupovat a prodávat kryptoměny

Otestovali jsme konvertibilní notebooky

Velký test 14 herních myší