MySQL GROUP BY og HAVING Klausul med eksempler
โก Smart oppsummering
SQL GROUP BY- og HAVING-klausuler gjรธr detaljerte rader om til sammendragsrapporter. GROUP BY skjuler rader som deler de samme verdiene til รฉn rad per gruppe, mens HAVING filtrerer disse gruppene etter at aggregerte funksjoner som COUNT er brukt.

Hva er SQL GROUP BY-klausulen?
GROUP BY-leddet er en SQL-kommando som brukes til grupperader som har samme verdierDen er skrevet i SELECT-setningen, og den brukes vanligvis sammen med aggregeringsfunksjoner for รฅ produsere sammendragsrapporter fra databasen.
Det er det den gjรธr: den oppsummerer data som holdes i databasen. Spรธrringer som inneholder GROUP BY-klausulen kalles grupperte spรธrringer, og de returnerer รฉn rad for hvert grupperte element.
SQL GROUP BY Syntaks
Nรฅ som formรฅlet med klausulen er klart, kan vi se pรฅ syntaksen til en grunnleggende gruppert spรธrring.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
HER
- "SELECT-setningerโฆยซer standardenยป SQL SELECT kommandoforespรธrsel.
- "GRUPPE AV kolonnenavn1ยซer klausulen som utfรธrer grouยปping basert pรฅ kolonnenavn1.
- "[, kolonnenavn2, โฆ]ยซer valgfritt og representerer andre kolonnenavn nรฅr gruppenping gjรธres pรฅ mer enn รฉn kolonne.
- "[HAVING tilstand]ยซยป er valgfritt og brukes til รฅ begrense radene som pรฅvirkes av GROUP BY-klausulen. Det ligner pรฅ HVOR klausul, bortsett fra at den pรฅfรธres etter at groben erping.
Grouping Bruk av en enkelt kolonne
Den raskeste mรฅten รฅ se effekten av SQL GROUP BY-klausulen pรฅ er รฅ sammenligne en ugruppert spรธrring med en gruppert spรธrring. Start med en enkel spรธrring som returnerer alle kjรธnnsoppfรธringer i medlemstabellen.
SELECT `gender` FROM `members`;
| kjรธnn |
|---|
| Hunn |
| Hunn |
| mann |
| Hunn |
| mann |
| mann |
| mann |
| mann |
| mann |
Ni rader returneres, og hver verdi gjentas. Anta at vi i stedet รธnsker de unike verdiene for kjรธnn. Spรธrringen nedenfor legger til GROUP BY-klausulen.
SELECT `gender` FROM `members` GROUP BY `gender`;
Utfรธrer skriptet ovenfor i MySQL Workbench mot myflixdb gir oss fรธlgende resultater.
| kjรธnn |
|---|
| Hunn |
| mann |
Merk at bare to rader er returnert, fordi tabellen bare inneholder to kjรธnnstyper. GROUP BY-klausulen grupperte alle ยซmannligeยป medlemmer sammen og returnerte รฉn rad for dem, og den gjorde det samme med ยซkvinneligeยป medlemmer.
Grouping Bruk av flere kolonner
Grouping pรฅ รฉn kolonne er ofte for grovt for en ekte rapport. GROUP BY godtar en kommaseparert liste over kolonner, og kombinasjonen av verdiene deres definerer hver gruppe.
Anta at vi รธnsker en liste over verdier for filmkategori-ID og de tilsvarende รฅrene filmene ble utgitt i. Observer fรธrst resultatet av denne enkle spรธrringen.
SELECT `category_id`, `year_released` FROM `movies`;
| kategori_id | รฅr_utgitt |
|---|---|
| 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 uthevede radene viser at resultatet inneholder duplikater. Hvis du kjรธrer den samme spรธrringen med GROUP BY, fjernes de.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Utfรธrer skriptet ovenfor i MySQL Arbeidsbenk mot myflixdb gir oss fรธlgende resultater vist nedenfor.
| kategori_id | รฅr_utgitt |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
GROUP BY-klausulen opererer pรฅ bรฅde category_id og year_released for รฅ identifisere unik rader. De to duplikatradene for kategori 6 i 2007 ble slรฅtt sammen til รฉn.
Tommelfingerregel: Hvis kategori-ID-en er den samme, men utgivelsesรฅret er forskjellig, behandles raden som unik. Hvis kategori-ID-en og utgivelsesรฅret er de samme for mer enn รฉn rad, er radene duplikater, og bare รฉn av dem vises.
Grouping og aggregatfunksjoner
Det er nyttig รฅ fjerne duplikater, men den virkelige kraften til grouping vises nรฅr den er paret med aggregerte funksjonerEn aggregert funksjon beregner รฉn verdi for hver gruppe: COUNT teller rader, SUM legger sammen verdier, og AVG, MIN og MAX beskriver spredningen.
Anta at vi รธnsker det totale antallet mannlige og kvinnelige medlemmer i databasen. Skriptet nedenfor gjรธr det.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Utfรธrer skriptet ovenfor i MySQL Arbeidsbenk mot myflixdb gir oss fรธlgende resultater.
| kjรธnn | ANTALL(`medlemsnummer`) |
|---|---|
| Hunn | 3 |
| mann | 6 |
Radene er gruppert etter hver unike kjรธnnsverdi, og antall rader i hver gruppe telles av aggregeringsfunksjonen COUNT. De ni medlemspostene kollapser i to sammendragsrader.
Begrense spรธrreresultater ved hjelp av HAVING-klausulen
Groupings er ikke alltid รธnskelig for hver rad i en tabell. Noen ganger mรฅ rapporten begrenses til et gitt kriterium, og det er HAVING-klausulens jobb.
Anta at vi vil vite alle utgivelsesรฅrene for filmkategori-ID 8. Skriptet nedenfor oppnรฅr det resultatet.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Utfรธrer skriptet ovenfor i MySQL Arbeidsbenk mot myflixdb gir oss fรธlgende resultater vist nedenfor.
| movie_id | tittel | direktรธr | รฅr_utgitt | kategori_id |
|---|---|---|---|---|
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 5 | Pappas smรฅjenter | NULL | 2007 | 8 |
Bare filmene med kategori-ID 8 har blitt beholdt av HAVING-betingelsen.
Advarsel: MySQL 5.7 og senere aktiverer ONLY_FULL_GROUP_BY-modusen som standard, og i den modusen avvises SELECT * med en GROUP BY-klausul fordi movie_id, title og director verken er gruppert eller aggregert. I produksjon, navngi de grupperte kolonnene eksplisitt, for eksempel VELG kategori_id, utgivelsesรฅr FRA filmer GROUP BY kategori_id, utgivelsesรฅr HAR kategori_id = 8;
HVOR vs. HA vs. GROUP BY vs. ORDER BY
Nybegynnere blander ofte disse fire klausulene, fordi alle former resultatsettet. Forskjellen ligger i nรฅr MySQL anvender dem: WHERE kjรธres fรธr radene grupperes, HAVING kjรธres etter, og ORDER BY kjรธres sist av alle.
| Klausul | Hva det gjรธr | Nรฅr den kjรธrer | Aksepterer aggregerte funksjoner |
|---|---|---|---|
| HVOR | Filtrerer individuelle rader fรธr noen grupperping. | Fรธr GROUP BY | Nei |
| GRUPPE AV | Skjulerer rader som deler de samme verdiene til รฉn rad per gruppe. | Etter HVOR | Ikke aktuelt |
| HAR | Filtrerer gruppene produsert av GROUP BY. | Etter GROUP BY | Ja, for eksempel HAVING COUNT(*) > 2 |
| REKKEFรLGE ETTER | Sorterer radene som overlever de foregรฅende klausulene. | Siste | Ja, et samlet alias kan sorteres |
Den praktiske konsekvensen er av ytelsesmessig art. Filtrering med WHERE fjerner rader fรธr gruppenping arbeidet starter, sรฅ en betingelse som ikke er avhengig av et aggregert resultat hรธrer hjemme i WHERE snarere enn HAVING.
