Na konci pololetí chce třídní učitelka vědět: jaký je průměr z matematiky, kolik známek kdo má a kdo má průměr horší než 2. Nechce vidět všech 500 známek, chce souhrnná čísla. A chce je seřazená.
SQL na to má řazení (ORDER BY) a agregační funkce, které z mnoha řádků spočítají jedno číslo.
SELECT sloupce FROM tabulka WHERE podmínka; vybere řádky a sloupce z tabulky.SELECT znamka FROM znamky WHERE predmet = 'M';ORDER BYSeřadí výsledek podle sloupce. ASC vzestupně (výchozí), DESC sestupně. Bez ORDER BY není pořadí řádků zaručené.ORDER BY prijmeni ASCAVG(znamka) spočítá průměr všech známek.| Funkce | Co spočítá |
|---|---|
COUNT(*) | počet řádků |
COUNT(sloupec) | počet řádků, kde sloupec není NULL |
SUM(sloupec) | součet |
AVG(sloupec) | aritmetický průměr (NULL vynechá) |
MIN(sloupec), MAX(sloupec) | nejmenší, největší hodnota |
| id | id_zaka | predmet | znamka |
|---|---|---|---|
| 1 | 1 | M | 1 |
| 2 | 1 | ČJ | 2 |
| 3 | 2 | M | 3 |
| 4 | 2 | ČJ | 4 |
| 5 | 3 | M | 2 |
| 6 | 4 | ČJ | 1 |
| 7 | 2 | M | 5 |
| Dotaz | Výsledek |
|---|---|
SELECT COUNT(*) FROM znamky; | 7 |
SELECT SUM(znamka) FROM znamky; | 18 |
SELECT MIN(znamka), MAX(znamka) FROM znamky; | 1, 5 |
SELECT AVG(znamka) FROM znamky WHERE predmet = 'M'; | 2.75 |
WHERE nejdřív nechá jen řádky matematiky, AVG pak počítá jen z nich.SELECT jmeno, prijmeni FROM zaci ORDER BY rok_narozeni DESC, prijmeni ASC; Nejdřív se řadí podle roku sestupně (nejmladší má nejvyšší rok). Když je rok stejný, rozhoduje příjmení.SELECT * FROM zaci WHERE AVG(znamka) > 2;HAVING (viz druhé vysvětlení) nebo do SELECT, ne do WHERE.WHERE posuzuje každý řádek zvlášť. Průměr ale vzniká až z více řádků, takže ho WHERE ještě nezná.
ORDER BY řadí výsledek (ASC vzestupně, DESC sestupně). Agregační funkce COUNT, SUM, AVG, MIN, MAX spočítají z mnoha řádků jednu hodnotu.Průměr všech známek je málo užitečný. Učitelka chce průměr zvlášť pro každý předmět nebo pro každého žáka. Představ si, že známky rozhází do hromádek podle předmětu a v každé hromádce spočítá průměr. Přesně to dělá GROUP BY.
A když chce vidět jen žáky s průměrem horším než 2, přidá podmínku na hromádky: HAVING.
COUNT, SUM, AVG, MIN, MAX – z hodnot více řádků spočítají jednu hodnotu.AVG(znamka)GROUP BYRozdělí řádky do skupin podle stejné hodnoty sloupce. Agregační funkce se pak spočítá pro každou skupinu zvlášť. Výsledek má jeden řádek za každou skupinu.GROUP BY predmet vytvoří skupinu M a skupinu ČJ.HAVINGPodmínka na celé skupiny. Smí obsahovat agregační funkce.HAVING AVG(znamka) > 2WHERE vs. HAVINGWHERE filtruje jednotlivé řádky před seskupením. HAVING filtruje hotové skupiny po seskupení.Nejdřív vyhoď neplatné známky (WHERE), pak skupiny s malým počtem (HAVING).| id | id_zaka | predmet | znamka |
|---|---|---|---|
| 1 | 1 | M | 1 |
| 2 | 1 | ČJ | 2 |
| 3 | 2 | M | 3 |
| 4 | 2 | ČJ | 4 |
| 5 | 3 | M | 2 |
| 6 | 4 | ČJ | 1 |
| 7 | 2 | M | 5 |
SELECT predmet, COUNT(*) AS pocet, AVG(znamka) AS prumerFROM znamkyGROUP BY predmet;| predmet | pocet | prumer |
|---|---|---|
| M | 4 | 2.75 |
| ČJ | 3 | 2.33… |
FROM – vezmi tabulku.WHERE – vyhoď nevyhovující řádky.GROUP BY – rozděl řádky do skupin.HAVING – vyhoď nevyhovující skupiny.SELECT – spočítej sloupce a agregace.ORDER BY – seřaď výsledek.SELECT id_zaka, AVG(znamka) FROM znamky GROUP BY id_zaka HAVING AVG(znamka) > 2; Skupiny: žák 1 (1, 2) = 1.5, žák 2 (3, 4, 5) = 4, žák 3 (2) = 2, žák 4 (1) = 1. Podmínku splní jen žák 2 s průměrem 4. Žák 3 má přesně 2, a to není víc než 2.SELECT trida, COUNT(*) FROM zaci WHERE rok_narozeni >= 2008 GROUP BY trida; WHERE vyřadí Tomáše (2007) ještě před seskupením. Výsledek: 2.A 2, 3.B 1, 1.C 1.SELECT predmet, id_zaka, AVG(znamka) FROM znamky GROUP BY predmet;SELECT mohou být jen sloupce z GROUP BY a agregace: SELECT predmet, AVG(znamka) … GROUP BY predmet;Ve skupině M je několik různých id_zaka. Který by se měl ukázat? Standard SQL takový dotaz odmítne (některé SŘBD vrátí náhodnou hodnotu).
GROUP BY rozdělí řádky do skupin a agregace se počítá pro každou zvlášť. WHERE filtruje řádky před seskupením, HAVING skupiny po něm. V SELECT smí být jen seskupované sloupce a agregace.