MySQL Klauzule GROUP BY a HAVING s příklady
⚡ Chytré shrnutí
Klauzule SQL GROUP BY a HAVING převádějí podrobné řádky na souhrnné sestavy. Funkce GROUP BY sbalí řádky, které sdílejí stejné hodnoty, do jednoho řádku na skupinu, zatímco funkce HAVING tyto skupiny filtruje po použití agregačních funkcí, jako je například COUNT.

Co je klauzule SQL GROUP BY?
Klauzule GROUP BY je příkaz SQL, který se používá seskupit řádky, které mají stejné hodnotyJe zapsán uvnitř příkazu SELECT a obvykle se používá společně s agregačními funkcemi k vytvoření souhrnných sestav z databáze.
To je to, co to dělá: shrnuje data uchovávané v databázi. Dotazy, které obsahují klauzuli GROUP BY, se nazývají seskupené dotazy a pro každou seskupenou položku vracejí jeden řádek.
SQL GROUP BY Syntaxe
Nyní, když je účel klauzule jasný, podívejme se na syntaxi základního seskupeného dotazu.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
ZDE
- "Příkazy SELECT…„je standard“ SQL SELECT dotaz na příkaz.
- "SKUPINA VYTVOŘENÁ název_sloupce1„je klauzule, která provádí skupinuping na základě sloupce_název1.
- "[, název_sloupec2, …]„“ je volitelný a představuje další názvy sloupců, když je skupinaping se provádí na více než jednom sloupci.
- "[MÁNÍ stavu]” je volitelný a používá se k omezení řádků ovlivněných klauzulí GROUP BY. Je podobný jako klauzule WHERE, s výjimkou toho, že se aplikuje po grouping.
Grouping Použití jednoho sloupce
Nejrychlejší způsob, jak vidět účinek klauzule SQL GROUP BY, je porovnat neseskupený dotaz se seskupeným. Začněte s jednoduchým dotazem, který vrací všechny položky pohlaví v tabulce členů.
SELECT `gender` FROM `members`;
| rod |
|---|
| Žena |
| Žena |
| Muž |
| Žena |
| Muž |
| Muž |
| Muž |
| Muž |
| Muž |
Vrátí se devět řádků a každá hodnota se opakuje. Předpokládejme, že místo toho chceme jedinečné hodnoty pro pohlaví. Následující dotaz přidává klauzuli GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Spuštění výše uvedeného skriptu v MySQL Workbench proti myflixdb nám dává následující výsledky.
| rod |
|---|
| Žena |
| Muž |
Všimněte si, že byly vráceny pouze dva řádky, protože tabulka obsahuje pouze dva typy pohlaví. Klauzule GROUP BY seskupila všechny členy typu „Muž“ a vrátila pro ně jeden řádek, a totéž udělala i s členy typu „Žena“.
Grouping Použití více sloupců
Grouping Hodnoty v jednom sloupci jsou pro skutečnou sestavu často příliš hrubé. Funkce GROUP BY akceptuje seznam sloupců oddělených čárkami a kombinace jejich hodnot definuje každou skupinu.
Předpokládejme, že chceme seznam hodnot category_id filmů a odpovídající roky, ve kterých byly filmy uvedeny. Nejprve si prohlédněte výstup tohoto jednoduchého dotazu.
SELECT `category_id`, `year_released` FROM `movies`;
| category_id | rok_vydáno |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Zvýrazněné řádky ukazují, že výsledek obsahuje duplikáty. Spuštění stejného dotazu s funkcí GROUP BY je odstraní.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Spuštění výše uvedeného skriptu v MySQL Workbench s myflixdb nám dává následující výsledky, které jsou uvedeny níže.
| category_id | rok_vydáno |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Klauzule GROUP BY pracuje s category_id i year_released a identifikuje tlačítko řádky. Dva duplicitní řádky pro kategorii 6 v roce 2007 se sloučily do jednoho.
Pravidlo: Pokud je ID kategorie stejné, ale rok vydání se liší, řádek se považuje za jedinečný. Pokud se ID kategorie a rok vydání shodují ve více než jednom řádku, řádky se jedná o duplikáty a zobrazí se pouze jeden z nich.
Grouping a agregační funkce
Odstraňování duplikátů je užitečné, ale skutečná síla skupiny...ping zobrazí se, když je spárován s agregační funkceAgregační funkce vypočítává jednu hodnotu pro každou skupinu: COUNT počítá řádky, SUM sčítá hodnoty a AVG, MIN a MAX popisují rozptyl.
Předpokládejme, že chceme zjistit celkový počet mužských a ženských členů v databázi. Následující skript to udělá.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Spuštění výše uvedeného skriptu v MySQL Workbench s myflixdb nám dává následující výsledky.
| rod | POČET(`číslo_členství`) |
|---|---|
| Žena | 3 |
| Muž | 6 |
Řádky jsou seskupeny podle každé jedinečné hodnoty pohlaví a počet řádků v každé skupině je počítán agregační funkcí COUNT. Devět členů záznamů se sbalí do dvou souhrnných řádků.
Omezení výsledků dotazu pomocí klauzule HAVING
GroupingNe vždy je potřeba použít parametry s pro každý řádek tabulky. Někdy musí být sestava omezena na dané kritérium, a to je úkol klauzule HAVING.
Předpokládejme, že chceme znát všechny roky vydání pro film s ID kategorie 8. Níže uvedený skript tohoto výsledku dosahuje.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Spuštění výše uvedeného skriptu v MySQL Workbench s myflixdb nám dává následující výsledky, které jsou uvedeny níže.
| movie_id | titul | ředitel | rok_vydáno | category_id |
|---|---|---|---|---|
| 9 | Honey mooneRS | John Schultz | 2005 | 8 |
| 5 | Tatínkovy holčičky | NULL | 2007 | 8 |
Podmínkou HAVING byly ponechány pouze filmy s ID kategorie 8.
Varování: MySQL Verze 5.7 a novější standardně povolují režim ONLY_FULL_GROUP_BY a v tomto režimu je příkaz SELECT * s klauzulí GROUP BY odmítnut, protože movie_id, title a director nejsou ani seskupeny, ani agregovány. V produkčním prostředí pojmenujte seskupené sloupce explicitně, například SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;
WHERE vs HAVING vs GROUP BY vs ORDER BY
Začátečníci často tyto čtyři klauzule pletou, protože všechny utvářejí výslednou sadu. Rozdíl spočívá v kdy MySQL Aplikuje je: WHERE se spustí před seskupením řádků, HAVING se spustí po a ORDER BY se spustí jako poslední ze všech.
| Doložka | Co to dělá | Když to běží | Přijímá agregační funkce |
|---|---|---|---|
| KDE | Filtruje jednotlivé řádky před jakoukoli skupinouping. | Před GROUP BY | Ne |
| SKUPINA VYTVOŘENÁ | Sbalí řádky sdílející stejné hodnoty do jednoho řádku na skupinu. | Po KDE | Nehodí |
| HAVING | Filtruje skupiny vytvořené funkcí GROUP BY. | Po GROUP BY | Ano, například HAVING COUNT(*) > 2 |
| SEŘADIT PODLE | Seřadí řádky, které přežijí předchozí klauzule. | Příjmení | Ano, agregovaný alias lze seřadit. |
Praktickým důsledkem je výkonnostní. Filtrování pomocí WHERE odstraňuje řádky před skupinou.ping práce začíná, takže podmínka, která nezávisí na agregovaném výsledku, patří do WHERE, nikoli do HAVING.
