MySQL Clauza GROUP BY și HAVING cu Exemple
⚡ Rezumat inteligent
Clauzele SQL GROUP BY și HAVING transformă rândurile detaliate în rapoarte sumarizate. GROUP BY restrânge rândurile care au aceleași valori într-un rând per grup, în timp ce HAVING filtrează aceste grupuri după ce au fost aplicate funcții agregate precum COUNT.

Ce este clauza SQL GROUP BY?
Clauza GROUP BY este o comandă SQL folosită pentru grupați rânduri care au aceleași valoriEste scrisă în interiorul instrucțiunii SELECT și este utilizată în mod normal împreună cu funcții agregate pentru a produce rapoarte sumarizate din baza de date.
Asta face: rezumă datele păstrate în baza de date. Interogările care conțin clauza GROUP BY se numesc interogări grupate și returnează un singur rând pentru fiecare element grupat.
SQL GROUP BY Sintaxă
Acum, că scopul clauzei este clar, să analizăm sintaxa unei interogări grupate de bază.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
AICI
- Instrucțiuni SELECT…„este standardul SQL SELECT interogare de comandă.
- A SE GRUPA CU nume_coloană1„este clauza care îndeplinește grupulping bazat pe numele_coloanei1.
- [, nume_coloană2, …]„” este opțional și reprezintă alte nume de coloane atunci când grupulping se face pe mai multe coloane.
- [AVÂND o afecțiune]„” este opțional și este utilizat pentru a restricționa rândurile afectate de clauza GROUP BY. Este similar cu clauza WHERE, cu excepția faptului că se aplică după grupareping.
Grouping Utilizarea unei singure coloane
Cea mai rapidă metodă de a observa efectul clauzei SQL GROUP BY este de a compara o interogare negrupată cu una grupată. Începeți cu o interogare simplă care returnează fiecare intrare de gen din tabelul membrilor.
SELECT `gender` FROM `members`;
| sex |
|---|
| Femeie |
| Femeie |
| Masculin |
| Femeie |
| Masculin |
| Masculin |
| Masculin |
| Masculin |
| Masculin |
Se returnează nouă rânduri și fiecare valoare se repetă. Să presupunem că dorim în schimb valorile unice pentru sex. Interogarea de mai jos adaugă clauza GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Executarea scriptului de mai sus în MySQL Banc de lucru împotriva myflixdb ne oferă următoarele rezultate.
| sex |
|---|
| Femeie |
| Masculin |
Rețineți că au fost returnate doar două rânduri, deoarece tabelul conține doar două tipuri de gen. Clauza GROUP BY a grupat toți membrii „Masculin” și a returnat un singur rând pentru aceștia și a făcut același lucru cu membrii „Feminin”.
Grouping Utilizarea mai multor coloane
Grouping O clasificare pe o singură coloană este adesea prea generală pentru un raport real. GROUP BY acceptă o listă de coloane separate prin virgulă, iar combinația valorilor acestora definește fiecare grup.
Să presupunem că dorim o listă de valori pentru movie category_id și anii corespunzători în care au fost lansate filmele. Observați mai întâi rezultatul acestei interogări simple.
SELECT `category_id`, `year_released` FROM `movies`;
| categorie_id | year_released |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Rândurile evidențiate arată că rezultatul conține duplicate. Executarea aceleiași interogări cu GROUP BY le elimină.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Executarea scriptului de mai sus în MySQL Workbench-ul pentru myflixdb ne oferă următoarele rezultate, prezentate mai jos.
| categorie_id | year_released |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Clauza GROUP BY operează atât asupra category_id, cât și asupra year_release pentru a identifica unic rânduri. Cele două rânduri duplicate pentru categoria 6 în 2007 s-au restrâns într-unul singur.
Regula generală: Dacă ID-ul categoriei este același, dar anul lansării este diferit, rândul este tratat ca unic. Dacă ID-ul categoriei și anul lansării sunt identice pentru mai multe rânduri, rândurile sunt duplicate și se afișează doar unul dintre ele.
Grouping și funcții agregate
Eliminarea duplicatelor este utilă, dar adevărata putere a grupăriiping apare atunci când este asociat cu funcții agregateO funcție agregată calculează o valoare pentru fiecare grup: COUNT numără rândurile, SUM adună valorile și AVG, MIN și MAX descriu dispersia.
Să presupunem că dorim numărul total de membri de sex masculin și feminin din baza de date. Scriptul de mai jos face acest lucru.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Executarea scriptului de mai sus în MySQL Workbench-ul pentru myflixdb ne dă următoarele rezultate.
| sex | COUNT(`număr_membru`) |
|---|---|
| Femeie | 3 |
| Masculin | 6 |
Rândurile sunt grupate după fiecare valoare unică de gen, iar numărul de rânduri din fiecare grup este numărat de funcția de agregare COUNT. Cele nouă înregistrări ale membrilor se combină în două rânduri sumar.
Restricționarea rezultatelor interogării folosind clauza HAVING
GroupingNu se dorește întotdeauna o funcție s pentru fiecare rând dintr-un tabel. Uneori, raportul trebuie restricționat la un anumit criteriu, iar aceasta este sarcina clauzei HAVING.
Să presupunem că vrem să știm toți anii de lansare pentru categoria de film ID 8. Scriptul de mai jos obține acest rezultat.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Executarea scriptului de mai sus în MySQL Workbench-ul pentru myflixdb ne oferă următoarele rezultate, prezentate mai jos.
| movie_id | titlu | director | year_released | categorie_id |
|---|---|---|---|---|
| 9 | Honey mooners | John Schultz | 2005 | 8 |
| 5 | Fetițele lui Tati | NULL | 2007 | 8 |
Doar filmele cu ID-ul de categorie 8 au fost păstrate de condiția HAVING.
Avertisment: MySQL 5.7 și versiunile ulterioare activează implicit modul ONLY_FULL_GROUP_BY, iar în acest mod, SELECT * cu o clauză GROUP BY este respins, deoarece movie_id, title și director nu sunt nici grupate, nici agregate. În producție, denumiți explicit coloanele grupate, de exemplu SELECT id_categorie, an_lansare FROM filme GROUP BY id_categorie, an_lansare HAVING id_categorie = 8;
UNDE vs. AVÂND vs. GROUP BY vs. ORDER BY
Începătorii combină frecvent aceste patru clauze, deoarece toate modelează setul de rezultate. Diferența constă în cand MySQL le aplică: WHERE se execută înainte ca rândurile să fie grupate, HAVING se execută după, iar ORDER BY se execută ultimul.
| Clauză | Ce face | Când rulează | Acceptă funcții agregate |
|---|---|---|---|
| UNDE | Filtrează rândurile individuale înaintea oricărui grupping. | Înainte de GROUP BY | Nu |
| A SE GRUPA CU | Restrânge rândurile care au aceleași valori într-un rând per grup. | După UNDE | Nu se aplică |
| AVÂND | Filtrează grupurile produse de GROUP BY. | După GROUP BY | Da, de exemplu, AVÂND COUNT(*) > 2 |
| COMANDA DE | Sortează rândurile care supraviețuiesc clauzelor anterioare. | Numele | Da, un alias agregat poate fi sortat |
Consecința practică este una de performanță. Filtrarea cu WHERE elimină rândurile dinaintea grupului.ping lucrul începe, deci o condiție care nu depinde de un rezultat agregat aparține WHERE mai degrabă decât HAVING.
