MySQL GROUP BY og HAVING Klausul med eksempler

⚡ Smart opsummering

SQL GROUP BY- og HAVING-klausuler omdanner detaljerede rækker til opsummeringsrapporter. GROUP BY skjuler rækker, der deler de samme værdier, til én række pr. gruppe, mens HAVING filtrerer disse grupper, efter at aggregeringsfunktioner som COUNT er blevet anvendt.

  • 📊 Kerneformål: GROUP BY grupperer rækker med identiske værdier og returnerer en enkelt række for hvert grupperet element.
  • 🧩 Gruppe med enkelt kolonneping: Grouping Medlemstabellen for køn skjuler ni rækker i to, en for kvinder og en for mænd.
  • 🔗 Gruppe med flere kolonnerping: Grouping på to kolonner behandler en række som unik, når en af ​​værdierne er forskellige, så kun nøjagtige dubletter skjules.
  • 🧮 Aggregeret parring: TÆL, SUM, AVG, MIN og MAX beregner én værdi pr. gruppe, hvilket producerer oversigtsrapporten.
  • 🚦 AT HAVE versus HVOR: WHERE filtrerer rækker før grouping, HAVING filtrerer grupperne bagefter, og kun HAVING accepterer aggregerede resultater.
  • ⚠️ Forsigtig med streng tilstand: Under ONLY_FULL_GROUP_BY skal hver valgte kolonne grupperes eller ombrydes i en aggregeringsfunktion.

SQL GROUP BY og HAVING-klausul

Hvad er SQL GROUP BY-klausulen?

GROUP BY-sætningen er en SQL-kommando, der bruges til grupperækker, der har samme værdierDet er skrevet i SELECT-sætningen, og det bruges normalt sammen med aggregeringsfunktioner til at producere opsummeringsrapporter fra databasen.

Det er, hvad den gør: den opsummerer data opbevares i databasen. Forespørgsler, der indeholder GROUP BY-klausulen, kaldes grupperede forespørgsler, og de returnerer en enkelt række for hvert grupperet element.

SQL GROUP BY Syntaks

Nu hvor formålet med klausulen er klart, kan vi se på syntaksen for en grundlæggende grupperet forespørgsel.

SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];

HER

  • "SELECT-sætninger…"er standarden SQL SELECT kommandoforespørgsel.
  • "GROUP BY kolonnenavn1" er den klausul, der udfører grouping baseret på kolonnenavn1.
  • "[, kolonnenavn2, …]" er valgfri og repræsenterer andre kolonnenavne, når gruppenping udføres på mere end én kolonne.
  • "[HAVER tilstand]" er valgfri og bruges til at begrænse de rækker, der påvirkes af GROUP BY-klausulen. Det minder om WHERE-klausul, bortset fra at den påføres efter jordenping.

Grouping Brug af en enkelt kolonne

Den hurtigste måde at se effekten af ​​SQL GROUP BY-klausulen på er at sammenligne en ugrupperet forespørgsel med en grupperet. Start med en simpel forespørgsel, der returnerer alle kønsposter i medlemstabellen.

SELECT `gender` FROM `members`;
køn
Kvinde
Kvinde
Mand
Kvinde
Mand
Mand
Mand
Mand
Mand

Ni rækker returneres, og hver værdi gentages. Antag, at vi i stedet ønsker de unikke værdier for køn. Forespørgslen nedenfor tilføjer GROUP BY-klausulen.

SELECT `gender` FROM `members` GROUP BY `gender`;

Udførelse af ovenstående script i MySQL Workbench mod myflixdb giver os følgende resultater.

køn
Kvinde
Mand

Bemærk, at kun to rækker er blevet returneret, fordi tabellen kun indeholder to kønstyper. GROUP BY-klausulen grupperede alle "Mandlige" medlemmer sammen og returnerede en enkelt række for dem, og den gjorde det samme med "Kvindelige" medlemmer.

Grouping Brug af flere kolonner

Grouping på én kolonne er ofte for grov til en rigtig rapport. GROUP BY accepterer en kommasepareret liste over kolonner, og kombinationen af ​​deres værdier definerer hver gruppe.

Antag, at vi ønsker en liste over værdier for filmkategori-id og de tilsvarende år, hvor filmene blev udgivet. Observer først outputtet fra denne simple forespørgsel.

SELECT `category_id`, `year_released` FROM `movies`;
kategori_id år_udgivet
1 2011
2 2008
NULL 2008
NULL 2010
8 2007
6 2007
6 2007
8 2005
NULL 2012
7 1920
8 NULL
8 1920

De fremhævede rækker viser, at resultatet indeholder dubletter. Hvis den samme forespørgsel udføres med GROUP BY, fjernes de.

SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;

Udførelse af ovenstående script i MySQL Workbench mod myflixdb giver os følgende resultater vist nedenfor.

kategori_id år_udgivet
NULL 2008
NULL 2010
NULL 2012
1 2011
2 2008
6 2007
7 1920
8 1920
8 2005
8 2007

GROUP BY-klausulen fungerer på både category_id og year_released for at identificere enestående rækker. De to duplikerede rækker for kategori 6 i 2007 blev slået sammen til én.

Tommelfingerregel: Hvis kategori-id'et er det samme, men udgivelsesåret er forskelligt, behandles rækken som unik. Hvis kategori-id'et og udgivelsesåret er det samme for mere end én række, er rækkerne dubletter, og kun én af dem vises.

Grouping og aggregatfunktioner

Det er nyttigt at fjerne dubletter, men den virkelige kraft ved groupping vises, når den er parret med samlede funktionerEn aggregeringsfunktion beregner én værdi for hver gruppe: COUNT tæller rækker, SUM lægger værdier sammen, og AVG, MIN og MAX beskriver spredningen.

Antag, at vi ønsker det samlede antal mandlige og kvindelige medlemmer i databasen. Scriptet nedenfor gør det.

SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;

Udførelse af ovenstående script i MySQL Workbench mod myflixdb giver os følgende resultater.

køn ANTAL(`medlemsnummer`)
Kvinde 3
Mand 6

Rækkerne er grupperet efter hver unikke kønsværdi, og antallet af rækker i hver gruppe tælles af den samlede funktion COUNT. De ni medlemsposter samles i to opsummeringsrækker.

Begrænsning af forespørgselsresultater ved hjælp af HAVING-klausulen

Groupings er ikke altid ønskede for hver række i en tabel. Nogle gange skal rapporten begrænses til et givet kriterium, og det er HAVING-klausulens opgave.

Antag, at vi vil kende alle udgivelsesårene for filmkategori-id 8. Scriptet nedenfor opnår dette resultat.

SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;

Udførelse af ovenstående script i MySQL Workbench mod myflixdb giver os følgende resultater vist nedenfor.

film_id titel direktør år_udgivet kategori_id
9 Honey moonERS John Schultz 2005 8
5 Daddy's Little Girls NULL 2007 8

Kun film med kategori-id 8 er blevet gemt af HAVING-betingelsen.

Advarsel: MySQL 5.7 og nyere aktiverer ONLY_FULL_GROUP_BY-tilstanden som standard, og i den tilstand afvises SELECT * med en GROUP BY-klausul, fordi movie_id, titel og instruktør hverken grupperes eller aggregeres. I produktion skal de grupperede kolonner navngives eksplicit, for eksempel VÆLG kategori_id, udgivelsesår FRA film GROUP BY kategori_id, udgivelsesår HAR kategori_id = 8;

HVOR vs. HAVE vs. GROUP BY vs. ORDER BY

Begyndere blander ofte disse fire klausuler, fordi de alle former resultatsættet. Forskellen ligger i hvornår MySQL anvender dem: WHERE køres før rækkerne grupperes, HAVING køres efter, og ORDER BY køres til sidst.

Klausul Hvad gør den Når den kører Accepterer aggregerede funktioner
HVOR Filtrerer individuelle rækker før enhver gruppeping. Før GROUP BY Ingen
GROUP BY Skjuler rækker, der deler de samme værdier, til én række pr. gruppe. Efter HVOR Ikke relevant
SOM Filtrerer de grupper, der er produceret af GROUP BY. Efter GROUP BY Ja, for eksempel HAVING COUNT(*) > 2
BESTIL BY Sorterer de rækker, der overlever de foregående klausuler. Efternavn Ja, et samlet alias kan sorteres

Den praktiske konsekvens er af ydeevnemæssig karakter. Filtrering med WHERE fjerner rækker før gruppenping arbejdet starter, så en betingelse, der ikke afhænger af et aggregeret resultat, hører hjemme i WHERE snarere end HAVING.

Ofte Stillede Spørgsmål

Ja. GROUP BY returnerer i sig selv én række pr. unik værdi, hvilket fjerner dubletter på stort set samme måde som SELECT DISTINCT. Aggregeringsfunktioner er kun nødvendige, når hver gruppe har brug for et beregnet tal.

Fejlen opstår, når en valgt kolonne hverken er angivet i GROUP BY eller omsluttet af en aggregeringsfunktion. MySQL kan ikke bestemme, hvilken værdi af den kolonne der skal vises for gruppen, så den afviser forespørgslen.

COUNT(*) tæller hver række i gruppen. COUNT(kolonne) tæller kun de rækker, hvor den pågældende kolonne ikke er NULL, så de to tal er forskellige, når kolonnen indeholder manglende værdier.

Ja. AI-assistenter i værktøjer som f.eks. MySQL Workbench oversæt en anmodning som "medlemmer pr. køn" til en grupperet forespørgsel. Tjek gruppenping kolonner selv, fordi en forkert gruppeping producerer totaler, der ser plausible ud, men er forkerte.

Ofte, ja. AI-forespørgselsassistenter markerer klassiske årsager såsom en JOIN der multiplicerer rækker før grouping, eller et filter placeret i HAVING i stedet for WHERE. Den endelige vurdering tilhører stadig den person, der kender dataene.

Opsummer dette indlæg med: