MySQL GROUP BY och HAVING Klausul med exempel
โก Smart sammanfattning
SQL GROUP BY- och HAVING-klausuler omvandlar detaljerade rader till sammanfattningsrapporter. GROUP BY komprimerar rader som delar samma vรคrden till en rad per grupp, medan HAVING filtrerar dessa grupper efter att aggregeringsfunktioner som COUNT har tillรคmpats.

Vad รคr SQL GROUP BY-klausulen?
GROUP BY-satsen รคr ett SQL-kommando som anvรคnds fรถr att grupprader som har samma vรคrdenDet skrivs inuti SELECT-satsen och anvรคnds normalt tillsammans med aggregeringsfunktioner fรถr att producera sammanfattningsrapporter frรฅn databasen.
Det รคr vad den gรถr: den sammanfattar data som finns i databasen. Frรฅgor som innehรฅller GROUP BY-klausulen kallas grupperade frรฅgor och de returnerar en enda rad fรถr varje grupperat objekt.
SQL GROUP BY Syntax
Nu nรคr syftet med klausulen รคr tydligt, titta pรฅ syntaxen fรถr en grundlรคggande grupperad frรฅga.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
HรR
- "SELECT-satserโฆโรคr standarden SQL SELECT kommandofrรฅga.
- "GRUPP AV kolumnnamn1โ รคr klausulen som utfรถr grouping baserat pรฅ kolumnnamn1.
- "[, kolumnnamn2, โฆ]โ รคr valfritt och representerar andra kolumnnamn nรคr gruppenping gรถrs pรฅ mer รคn en kolumn.
- "[HA villkor]โ รคr valfritt och anvรคnds fรถr att begrรคnsa raderna som pรฅverkas av GROUP BY-klausulen. Det liknar VAR klausul, fรถrutom att den appliceras efter markenping.
Grouping Anvรคnda en enda kolumn
Det snabbaste sรคttet att se effekten av SQL GROUP BY-klausulen รคr att jรคmfรถra en ogrupperad frรฅga med en grupperad. Bรถrja med en enkel frรฅga som returnerar varje kรถnspost i medlemstabellen.
SELECT `gender` FROM `members`;
| kรถn |
|---|
| Kvinna |
| Kvinna |
| man |
| Kvinna |
| man |
| man |
| man |
| man |
| man |
Nio rader returneras och varje vรคrde upprepas. Anta att vi istรคllet vill ha de unika vรคrdena fรถr kรถn. Frรฅgan nedan lรคgger till GROUP BY-klausulen.
SELECT `gender` FROM `members` GROUP BY `gender`;
Exekvera skriptet ovan i MySQL Arbetsbรคnk mot myflixdb ger oss fรถljande resultat.
| kรถn |
|---|
| Kvinna |
| man |
Observera att endast tvรฅ rader har returnerats, eftersom tabellen endast innehรฅller tvรฅ kรถnstyper. GROUP BY-klausulen grupperade alla "Manliga" medlemmar och returnerade en enda rad fรถr dem, och den gjorde detsamma med "Kvinnliga" medlemmar.
Grouping Anvรคnda flera kolumner
Grouping pรฅ en kolumn รคr ofta fรถr grovt fรถr en riktig rapport. GROUP BY accepterar en kommaseparerad lista med kolumner, och kombinationen av deras vรคrden definierar varje grupp.
Anta att vi vill ha en lista med vรคrden fรถr filmkategori-id och motsvarande รฅr dรฅ filmerna slรคpptes. Observera fรถrst resultatet av denna enkla frรฅga.
SELECT `category_id`, `year_released` FROM `movies`;
| kategori_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 |
De markerade raderna visar att resultatet innehรฅller dubbletter. Om du kรถr samma frรฅga med GROUP BY tas de bort.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Exekvera skriptet ovan i MySQL Workbench mot myflixdb ger oss fรถljande resultat som visas nedan.
| kategori_id | year_released |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
GROUP BY-klausulen fungerar pรฅ bรฅde category_id och year_released fรถr att identifiera unika rader. De tvรฅ duplicerade raderna fรถr kategori 6 รฅr 2007 slogs ihop till en.
Tumregel: Om kategori-ID:t รคr detsamma men utgivningsรฅret รคr ett annat, behandlas raden som unik. Om kategori-ID:t och utgivningsรฅret รคr desamma fรถr mer รคn en rad, รคr raderna dubbletter och endast en av dem visas.
Grouping och aggregerade funktioner
Att ta bort dubbletter รคr anvรคndbart, men den verkliga kraften i groupping visas nรคr den รคr parad med aggregerade funktionerEn aggregeringsfunktion berรคknar ett vรคrde fรถr varje grupp: COUNT rรคknar rader, SUM adderar vรคrden och AVG, MIN och MAX beskriver spridningen.
Anta att vi vill ha det totala antalet manliga och kvinnliga medlemmar i databasen. Skriptet nedan gรถr det.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Exekvera skriptet ovan i MySQL Workbench mot myflixdb ger oss fรถljande resultat.
| kรถn | ANTAL(`medlemsnummer`) |
|---|---|
| Kvinna | 3 |
| man | 6 |
Raderna grupperas efter varje unikt kรถnsvรคrde, och antalet rader i varje grupp rรคknas av aggregeringsfunktionen COUNT. De nio medlemsposterna delas upp i tvรฅ sammanfattningsrader.
Begrรคnsa frรฅgeresultat med hjรคlp av HAVING-klausulen
Groupings รถnskas inte alltid fรถr varje rad i en tabell. Ibland mรฅste rapporten begrรคnsas till ett givet kriterium, och det รคr HAVING-klausulens uppgift.
Anta att vi vill veta alla utgivningsรฅr fรถr filmkategori-id 8. Manuset nedan uppnรฅr det resultatet.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Exekvera skriptet ovan i MySQL Workbench mot myflixdb ger oss fรถljande resultat som visas nedan.
| movie_id | rubricerade | direktรถr | year_released | kategori_id |
|---|---|---|---|---|
| 9 | Honey moonERS | John Schultz | 2005 | 8 |
| 5 | Pappas smรฅ flickor | NULL | 2007 | 8 |
Endast filmer med kategori-id 8 har behรฅllits av HAVING-villkoret.
Varning: MySQL 5.7 och senare aktiverar lรคget ONLY_FULL_GROUP_BY som standard, och i det lรคget avvisas SELECT * med en GROUP BY-klausul, eftersom movie_id, titel och regissรถr varken grupperas eller aggregeras. I produktion, namnge de grupperade kolumnerna explicit, till exempel VรLJ kategori_id, utgivningsรฅr FRร N filmer GROUP BY kategori_id, utgivningsรฅr HAR kategori_id = 8;
VAR vs HA vs GROUP BY vs ORDER BY
Nybรถrjare blandar ofta dessa fyra klausuler, eftersom alla formar resultatmรคngden. Skillnaden ligger i nรคr MySQL tillรคmpar dem: WHERE kรถrs innan raderna grupperas, HAVING kรถrs efter och ORDER BY kรถrs sist av alla.
| Klausul | Vad den gรถr | Nรคr den kรถrs | Accepterar aggregerade funktioner |
|---|---|---|---|
| VAR | Filtrerar enskilda rader fรถre eventuella grupperping. | Fรถre GROUP BY | Nej |
| GRUPP AV | Minimerar rader som delar samma vรคrden till en rad per grupp. | Efter VAR | ej tillรคmplig |
| HAR | Filtrerar grupperna som produceras av GROUP BY. | Efter GROUP BY | Ja, till exempel HAVING COUNT(*) > 2 |
| SORTERA EFTER | Sorterar de rader som รถverlever de fรถregรฅende klausulerna. | Efternamn | Ja, ett aggregerat alias kan sorteras |
Den praktiska konsekvensen รคr av prestandamรคssig betydelse. Filtrering med WHERE tar bort rader fรถre gruppenping arbetet startar, sรฅ ett villkor som inte รคr beroende av ett aggregerat resultat hรถr hemma i WHERE snarare รคn HAVING.
