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.

  • 📊 Scop principal: Funcția GROUP BY grupează rândurile cu valori identice și returnează un singur rând pentru fiecare element grupat.
  • 🧩 Grup cu o singură coloanăping: Grouping Tabelul membrilor după sex restrânge nouă rânduri în două, unul pentru Femeie și unul pentru Bărbați.
  • 🔗 Grupare cu mai multe coloaneping: Grouping pe două coloane tratează un rând ca unic atunci când oricare dintre valori diferă, astfel încât doar duplicatele exacte se restrâng.
  • 🧮 Împerechere agregată: NUMĂRĂ, SUMĂ, AVG, MIN și MAX calculează o valoare per grup, ceea ce produce raportul sumar.
  • 🚦 AVÂND Versus UNDE: WHERE filtrează rândurile înainte de grupping, HAVING filtrează grupurile ulterior și acceptă doar rezultate agregate.
  • ⚠️ Atenție la modul strict: Sub ONLY_FULL_GROUP_BY, fiecare coloană selectată trebuie grupată sau încapsulată într-o funcție agregată.

Clauza SQL GROUP BY și HAVING

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.

Întrebări frecvente

Da. Funcția GROUP BY returnează de la sine câte un rând per valoare unică, ceea ce elimină duplicatele în același mod ca și funcția SELECT DISTINCT. Funcțiile de agregare sunt necesare numai atunci când fiecare grup are nevoie de o cifră calculată.

Eroarea apare atunci când o coloană selectată nu este listată în GROUP BY și nici nu este încapsulată într-o funcție agregată. MySQL nu poate decide ce valoare a acelei coloane să afișeze pentru grup, așa că refuză interogarea.

COUNT(*) numără fiecare rând din grup. COUNT(coloană) numără doar rândurile în care acea coloană nu este NULL, deci cele două cifre diferă ori de câte ori coloana conține valori lipsă.

Da. Asistenți AI în instrumente precum MySQL Banc de lucru traduceți o cerere precum „membri pe gen” într-o interogare grupată. Verificați grupulping coloane pe tine însuți, pentru că un grup greșitping produce totaluri care par plauzibile, dar sunt incorecte.

Adesea, da. Asistenții de interogare cu inteligență artificială semnalează cauze clasice, cum ar fi JOIN care înmulțește rândurile înainte de grupping, sau un filtru plasat în HAVING în loc de WHERE. Judecata finală aparține în continuare persoanei care cunoaște datele.

Rezumați această postare cu: