SQL GROUP BY a agregační funkce: Shrňte svá data
Published: 2026-04-08
GROUP BY sloučí více řádků, které sdílejí stejnou hodnotu v jednom nebo více sloupcích, do jednoho souhrnného řádku. V kombinaci s agregačními funkcemi jako COUNT, SUM, AVG, MIN a MAX tvoří základ téměř každého reportovacího a analytického dotazu. GROUP BY je podporováno ve všech SQL databázích včetně SQLite, PostgreSQL, MySQL, SQL Server a Oracle.
Ukázková data
Ve všech příkladech používáme dvě tabulky:
Tabulka employees:
| id | name | department | hire_date | salary |
|---|---|---|---|---|
| 1 | Alice | Engineering | 2023-01-15 | 95000 |
| 2 | Bob | Engineering | 2023-06-01 | 85000 |
| 3 | Carol | Engineering | 2024-03-10 | 85000 |
| 4 | Dave | Sales | 2023-02-20 | 72000 |
| 5 | Eve | Sales | 2023-09-05 | 68000 |
| 6 | Frank | Sales | 2024-01-15 | 65000 |
| 7 | Grace | Marketing | 2023-04-01 | 82000 |
| 8 | Henry | Marketing | 2024-06-01 | 70000 |
Tabulka orders:
| id | customer | product | category | quantity | unit_price | order_date | status |
|---|---|---|---|---|---|---|---|
| 1 | Acme Corp | Laptop Pro | Electronics | 3 | 1299.99 | 2026-01-05 | delivered |
| 2 | Acme Corp | Wireless Mouse | Electronics | 10 | 29.99 | 2026-01-12 | delivered |
| 3 | Globex | Office Chair | Furniture | 5 | 249.99 | 2026-01-18 | delivered |
| 4 | Globex | Standing Desk | Furniture | 2 | 599.99 | 2026-01-20 | shipped |
| 5 | Initech | Notebook Pack | Stationery | 20 | 12.99 | 2026-02-03 | delivered |
| 6 | Initech | Pen Set | Stationery | 15 | 8.99 | 2026-02-07 | delivered |
| 7 | Acme Corp | Monitor 27" | Electronics | 4 | 399.99 | 2026-02-14 | delivered |
| 8 | Umbrella Ltd | Laptop Pro | Electronics | 2 | 1299.99 | 2026-02-20 | cancelled |
| 9 | Umbrella Ltd | Desk Lamp | Furniture | 8 | 39.99 | 2026-03-01 | delivered |
| 10 | Globex | Wireless Mouse | Electronics | 12 | 29.99 | 2026-03-05 | shipped |
| 11 | Initech | Monitor 27" | Electronics | 1 | 399.99 | 2026-03-10 | delivered |
| 12 | Acme Corp | Standing Desk | Furniture | 1 | 599.99 | 2026-03-15 | processing |
Syntaxe GROUP BY
SELECT column1, aggregate_function(column2)
FROM table_name
WHERE condition
GROUP BY column1
HAVING aggregate_condition
ORDER BY column1;
- GROUP BY — jeden nebo více sloupců, jejichž jedinečné kombinace hodnot definují každou skupinu
- Agregační funkce — spočítají jednu hodnotu ze všech řádků ve skupině
- HAVING — filtruje skupiny (podobně jako WHERE, ale pro seskupené výsledky)
- Každý sloupec v SELECT, který není uvnitř agregační funkce, musí být uveden v GROUP BY
Pořadí vykonávání SQL
SQL klauzule se zapisují v jednom pořadí, ale vykonávají se v jiném. Pochopení tohoto pořadí vysvětluje, proč HAVING může odkazovat na agregační funkce, ale WHERE ne, a proč nemůžete použít alias ze SELECT v klauzuli HAVING.
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
| Krok | Klauzule | Co se děje |
|---|---|---|
| 1 | FROM | Načtou se tabulky a vyhodnotí se případné JOINy |
| 2 | WHERE | Filtrování jednotlivých řádků — agregační funkce zde nejsou povoleny |
| 3 | GROUP BY | Zbývající řádky se sloučí do skupin |
| 4 | HAVING | Filtrování skupin — agregační funkce zde jsou povoleny |
| 5 | SELECT | Spočítají se výstupní sloupce a aliasy |
| 6 | ORDER BY | Seřadí se výsledná množina řádků |
Proto WHERE status = 'delivered' běží před seskupením (rychlý filtr na úrovni řádků), zatímco HAVING COUNT(*) > 2 běží po seskupení (filtruje celé skupiny).
COUNT()
COUNT(*) počítá všechny řádky ve skupině. COUNT(column) počítá nenulové (non-NULL) hodnoty v daném sloupci.
Příklad: Počet zaměstnanců v oddělení
Příklad: Počet objednávek na zákazníka
Příklad: Počet doručených vs. ostatních stavů
Počítejte pouze objednávky splňující podmínku pomocí COUNT s výrazem CASE:
SUM()
SUM(column) sečte všechny hodnoty ve skupině pro číselný sloupec.
Příklad: Celková mzda na oddělení
Příklad: Celkové tržby na kategorii
Spočítejte tržby jako quantity * unit_price:
Příklad: Tržby podle zákazníka a kategorie
Seskupte podle více sloupců, abyste tržby dále rozčlenili:
AVG()
AVG(column) vrací aritmetický průměr všech nenulových (non-NULL) hodnot ve skupině.
Příklad: Průměrná mzda na oddělení
Příklad: Průměrná hodnota objednávky na zákazníka
MIN() a MAX()
MIN(column) a MAX(column) vrací nejmenší a největší hodnotu ve skupině.
Příklad: Rozpětí mezd na oddělení
Příklad: První a poslední datum objednávky na zákazníka
Kombinování více agregací
V jednom dotazu můžete zkombinovat libovolný počet agregačních funkcí.
Příklad: Kompletní souhrn oddělení
Příklad: Souhrn objednávek na zákazníka
HAVING
HAVING filtruje skupiny po agregaci — je to ekvivalent WHERE pro seskupené výsledky.
Příklad: Oddělení s více než dvěma zaměstnanci
Příklad: Zákazníci s celkovými tržbami nad 2000
Příklad: Kategorie s průměrnou hodnotou objednávky pod 500
WHERE vs. HAVING
WHERE filtruje jednotlivé řádky před seskupením. HAVING filtruje skupiny po agregaci.
Příklad: Tržby pouze z doručených objednávek na zákazníka
Použijte WHERE k vyloučení řádků před seskupením a poté HAVING k filtrování výsledků:
GROUP BY s JOINy
Můžete seskupovat data, která se nacházejí v několika tabulkách, tím, že je nejprve spojíte (JOIN).
Příklad: Tržby na oddělení přes JOIN na zaměstnance
Příklad: Počet objednávek a tržby podle kategorie a měsíce
GROUP BY s výrazy
Můžete seskupovat podle vypočtených výrazů, nejen podle prostých sloupců.
Příklad: Zaměstnanci přijatí v jednotlivých letech
Příklad: Objednávky podle měsíců
COUNT(DISTINCT)
COUNT(DISTINCT column) počítá počet jedinečných hodnot ve skupině.
Příklad: Jedinečné produkty objednané na zákazníka
Filtrování skupin s více podmínkami
HAVING podporuje libovolný booleovský výraz, včetně kombinací AND/OR.
Příklad: Hodnotní aktivní zákazníci
Najděte zákazníky s více než jednou objednávkou a celkovými tržbami nad 1000:
Praktický příklad: Prodejní report
Zkombinujme vše do kompletního souhrnného reportu prodeje.
Příklad: Report výkonnosti kategorií
Příklad: Nejvýnosnější produkt
GROUP BY vs. okenní funkce
GROUP BY sloučí řádky do jednoho řádku na skupinu. Okenní funkce ponechají všechny řádky a přidají vypočtený sloupec — podrobnosti najdete v tutoriálu k SQL okenním funkcím.
Příklad: GROUP BY vrací jeden řádek na oddělení
Příklad: Okenní funkce ponechá všechny řádky
Běžné případy použití GROUP BY
- Reportovací dashboardy — Souhrny součtů, průměrů a počtů podle kategorií nebo časových období
- Analýza headcountu — Počty zaměstnanců, uživatelů nebo záznamů podle skupin
- Rozpad tržeb — Celkové a průměrné tržby podle produktu, regionu nebo zákazníka
- Analýza trendů — Seskupení podle měsíců nebo let pro odhalení vzorců v čase
- Top-N v rámci skupiny — V kombinaci s poddotazy nebo CTE najdete nejlepšího „výkonáře“ v každé skupině
- Validace dat — Počítání duplicit nebo NULL hodnot napříč skupinami
- Cohort analýza — Seskupení uživatelů podle data registrace nebo behaviorálního segmentu
Tipy pro výkon
- Indexujte sloupce v GROUP BY — Indexy na seskupovaných sloupcích urychlují krok třídění a seskupování
- Filtrujte co nejdříve pomocí WHERE — Zmenšení počtu řádků před seskupením je rychlejší než filtrování až po něm pomocí HAVING
- Vyhněte se SELECT * — Vybírejte jen sloupce, které skutečně potřebujete; agregační operace těží z užších dat
- Používejte „covering“ indexy — Index, který obsahuje jak sloupec z GROUP BY, tak agregovaný sloupec, může zabránit úplnému skenu tabulky
- Zvažte materializované pohledy — Pro často počítané agregace nad velkými tabulkami některé databáze podporují předpočítané souhrny
Shrnutí
- GROUP BY sloučí řádky, které sdílejí stejné hodnoty ve sloupcích, do jednoho souhrnného řádku pro každou jedinečnou kombinaci
- COUNT(*) počítá všechny řádky; COUNT(column) počítá nenulové hodnoty; COUNT(DISTINCT column) počítá jedinečné hodnoty
- SUM sčítá číselné hodnoty; AVG počítá průměr; MIN / MAX hledají krajní hodnoty
- Každý sloupec v SELECT musí buď být v GROUP BY, nebo být obalen agregační funkcí
- WHERE filtruje řádky před seskupením; HAVING filtruje skupiny po agregaci
- Můžete GROUP BY používat i s výrazy (např.
SUBSTR(date, 1, 7)pro seskupení na úrovni měsíců) - Spojení tabulek před seskupením vám umožní zkombinovat data z více zdrojů do jednoho reportu
- Použijte okenní funkce místo GROUP BY, když potřebujete metriky na úrovni skupin, ale nechcete přijít o jednotlivé řádky
Zkuste kombinovat GROUP BY s JOINy, výrazy CASE a klauzulemi HAVING a vytvořte si reporty, které vaše datová analýza potřebuje!