MySQL GROUP BY en HAVING-clausule met voorbeelden

โšก Slimme samenvatting

De SQL-clausules GROUP BY en HAVING zetten gedetailleerde rijen om in samenvattende rapporten. GROUP BY voegt rijen met dezelfde waarden samen tot รฉรฉn rij per groep, terwijl HAVING die groepen filtert nadat aggregatiefuncties zoals COUNT zijn toegepast.

  • ๐Ÿ“Š Kerndoel: GROUP BY groepeert rijen met identieke waarden en retourneert รฉรฉn rij voor elk gegroepeerd item.
  • ๐Ÿงฉ Enkele kolomgroepping: Grouping De tabel met leden op basis van geslacht voegt negen rijen samen tot twee, รฉรฉn voor vrouwen en รฉรฉn voor mannen.
  • ๐Ÿ”— Groep met meerdere kolommenping: Grouping Bij twee kolommen wordt een rij als uniek beschouwd wanneer een van beide waarden verschilt, waardoor alleen exacte duplicaten worden samengevoegd.
  • ๐Ÿงฎ Gecombineerde koppeling: TELLEN, SOMMEN, AVG, MIN en MAX berekenen รฉรฉn waarde per groep, wat resulteert in het samenvattende rapport.
  • ๐Ÿšฆ HEBBEN versus WAAR: WHERE filtert rijen vรณรณr groeperingpingHAVING filtert de groepen vervolgens, en alleen HAVING accepteert geaggregeerde resultaten.
  • โš ๏ธ Waarschuwing voor strikte modus: Bij ONLY_FULL_GROUP_BY moet elke geselecteerde kolom worden gegroepeerd of opgenomen in een aggregatiefunctie.

SQL GROUP BY en HAVING-clausule

Wat is de SQL GROUP BY-clausule?

De GROUP BY-clausule is een SQL-opdracht die wordt gebruikt groepeer rijen die dezelfde waarden hebbenHet wordt binnen de SELECT-instructie geschreven en wordt normaal gesproken samen met aggregatiefuncties gebruikt om samenvattende rapporten uit de database te genereren.

Dat is wat het doet: het vat gegevens samen opgeslagen in de database. Query's die de GROUP BY-clausule bevatten, worden gegroepeerde query's genoemd en retourneren รฉรฉn rij voor elk gegroepeerd item.

SQL GROUP BY-syntaxis

Nu het doel van de clausule duidelijk is, bekijk dan de syntaxis van een eenvoudige gegroepeerde query.

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

HIER

  • "SELECT-instructiesโ€ฆ" is de standaard SQL KIEZEN opdrachtquery.
  • "GROEP DOOR kolomnaam1" is de clausule die de groepstaak uitvoertping gebaseerd op kolomnaam1.
  • "[, kolomnaam2, โ€ฆ]" is optioneel en vertegenwoordigt andere kolomnamen wanneer de groepping wordt uitgevoerd op meer dan รฉรฉn kolom.
  • "[AANDOENING HEBBEN]" is optioneel en wordt gebruikt om de rijen te beperken die door de GROUP BY-clausule worden beรฏnvloed. Het is vergelijkbaar met de WHERE-clausule, behalve dat het wordt toegepast na de groepping.

Grouping Een enkele kolom gebruiken

De snelste manier om het effect van de SQL GROUP BY-clausule te zien, is door een ongegroepeerde query te vergelijken met een gegroepeerde query. Begin met een eenvoudige query die alle geslachtsvermeldingen in de tabel 'members' retourneert.

SELECT `gender` FROM `members`;
geslacht
Vrouwen
Vrouwen
Mannen
Vrouwen
Mannen
Mannen
Mannen
Mannen
Mannen

Er worden negen rijen geretourneerd en elke waarde wordt herhaald. Stel dat we in plaats daarvan de unieke waarden voor geslacht willen. De onderstaande query voegt de GROUP BY-clausule toe.

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

Voer het bovenstaande script uit in MySQL Werkbank tegen myflixdb geeft ons de volgende resultaten.

geslacht
Vrouwen
Mannen

Merk op dat er slechts twee rijen zijn geretourneerd, omdat de tabel slechts twee geslachtstypen bevat. De GROUP BY-clausule groepeerde alle "mannelijke" leden en gaf รฉรฉn rij voor hen terug, en deed hetzelfde met de "vrouwelijke" leden.

Grouping Meerdere kolommen gebruiken

Grouping Een filter op รฉรฉn kolom is vaak te grof voor een echt rapport. GROUP BY accepteert een door komma's gescheiden lijst met kolommen, en de combinatie van hun waarden definieert elke groep.

Stel dat we een lijst willen met de category_id-waarden van films en de bijbehorende jaartallen waarin de films zijn uitgebracht. Bekijk eerst de uitvoer van deze eenvoudige query.

SELECT `category_id`, `year_released` FROM `movies`;
categorie ID jaar_uitgebracht
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 gemarkeerde rijen laten zien dat het resultaat duplicaten bevat. Door dezelfde query met GROUP BY uit te voeren, worden deze verwijderd.

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

Voer het bovenstaande script uit in MySQL Workbench levert de volgende resultaten op in combinatie met myflixdb, zoals hieronder weergegeven.

categorie ID jaar_uitgebracht
NULL 2008
NULL 2010
NULL 2012
1 2011
2 2008
6 2007
7 1920
8 1920
8 2005
8 2007

De GROUP BY-clausule werkt op zowel category_id als year_released om te identificeren unieke rijen. De twee dubbele rijen voor categorie 6 in 2007 zijn samengevoegd tot รฉรฉn.

Vuistregel: Als het categorie-ID hetzelfde is, maar het jaar van uitgave verschilt, wordt de rij als uniek beschouwd. Als het categorie-ID en het jaar van uitgave voor meerdere rijen hetzelfde zijn, worden de rijen als duplicaten beschouwd en wordt er slechts รฉรฉn weergegeven.

Grouping en aggregatiefuncties

Het verwijderen van duplicaten is nuttig, maar de echte kracht van groeperen schuilt in...ping verschijnt wanneer het wordt gecombineerd met geaggregeerde functiesEen aggregatiefunctie berekent รฉรฉn waarde voor elke groep: COUNT telt rijen, SUM telt waarden op en AVG, MIN en MAX beschrijven de spreiding.

Stel dat we het totale aantal mannelijke en vrouwelijke leden in de database willen weten. Het onderstaande script doet dat.

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

Voer het bovenstaande script uit in MySQL Workbench levert de volgende resultaten op bij het gebruik van myflixdb.

geslacht COUNT(`membership_number`)
Vrouwen 3
Mannen 6

De rijen worden gegroepeerd op basis van elke unieke geslachtswaarde, en het aantal rijen binnen elke groep wordt geteld door de aggregatiefunctie COUNT. De negen ledenrecords worden samengevoegd tot twee samenvattingsrijen.

Queryresultaten beperken met behulp van de HAVING-clausule

GroupingEen rapport hoeft niet altijd voor elke rij in een tabel te worden gegenereerd. Soms moet het rapport worden beperkt tot een bepaald criterium, en dat is de taak van de HAVING-clausule.

Stel dat we alle releasejaren willen weten voor films met categorie-ID 8. Het onderstaande script levert dat resultaat op.

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

Voer het bovenstaande script uit in MySQL Workbench levert de volgende resultaten op in combinatie met myflixdb, zoals hieronder weergegeven.

film_id titel directeur jaar_uitgebracht categorie ID
9 Honey mooners John Schulz 2005 8
5 Papa's kleine meisjes NULL 2007 8

Alleen films met categorie-ID 8 zijn behouden op basis van de HAVING-voorwaarde.

Waarschuwing: MySQL Vanaf versie 5.7 is de modus ONLY_FULL_GROUP_BY standaard ingeschakeld. In deze modus wordt een SELECT * query met een GROUP BY-clausule geweigerd, omdat movie_id, title en director niet gegroepeerd of geaggregeerd zijn. In een productieomgeving is het raadzaam de gegroepeerde kolommen expliciet te benoemen, bijvoorbeeld: SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;

WAAR vs. HEBBEN vs. GROUP BY vs. ORDER BY

Beginners halen deze vier bijzinnen vaak door elkaar, omdat ze alle vier de resultaatset bepalen. Het verschil zit hem in... wanneer MySQL De volgende voorwaarden worden toegepast: WHERE wordt uitgevoerd voordat de rijen worden gegroepeerd, HAVING wordt uitgevoerd erna, en ORDER BY wordt als laatste uitgevoerd.

Clausule Wat het doet Als het draait Accepteert aggregatiefuncties
WAAR Filtert individuele rijen vรณรณrdat er groepen worden gefilterd.ping. Voor GROEPEREN OP Nee
GROEP DOOR Voegt rijen met dezelfde waarden samen tot รฉรฉn rij per groep. Na WAAR Niet van toepassing
HEBBEN Filtert de groepen die door GROUP BY worden gegenereerd. Na GROEPEREN OP Ja, bijvoorbeeld HAVING COUNT(*) > 2
BESTELLING DOOR Sorteert de rijen die de voorgaande clausules overleven. Achternaam* Ja, een aggregaatalias kan worden gesorteerd.

Het praktische gevolg is een prestatieprobleem. Filteren met WHERE verwijdert rijen vรณรณr de groep.ping Het werk begint, dus een voorwaarde die niet afhankelijk is van een totaalresultaat hoort thuis in de WHERE-clausule in plaats van in de HAVING-clausule.

Veelgestelde vragen

Ja. GROUP BY retourneert op zichzelf รฉรฉn rij per unieke waarde, waardoor duplicaten op vrijwel dezelfde manier worden verwijderd als SELECT DISTINCT. Aggregatiefuncties zijn alleen nodig wanneer elke groep een berekend getal nodig heeft.

De foutmelding verschijnt wanneer een geselecteerde kolom niet is opgenomen in GROUP BY en ook niet is opgenomen in een aggregatiefunctie. MySQL Het systeem kan niet bepalen welke waarde van die kolom voor de groep moet worden weergegeven, waardoor de query wordt geweigerd.

COUNT(*) telt elke rij in de groep. COUNT(kolom) telt alleen de rijen waar die kolom niet voorkomt. NULLDe twee cijfers verschillen dus wanneer de kolom ontbrekende waarden bevat.

Ja. AI-assistenten in tools zoals MySQL Werkbank Vertaal een verzoek zoals 'leden per geslacht' naar een gegroepeerde query. Controleer de groep.ping kolommen zelf, want een verkeerde groepping produceert totalen die aannemelijk lijken, maar onjuist zijn.

Vaak wel. AI-zoekassistenten signaleren klassieke oorzaken zoals een AANMELDEN dat vermenigvuldigt rijen vรณรณr groeperingpingOf een filter dat in HAVING in plaats van WHERE is geplaatst. Het uiteindelijke oordeel blijft echter bij de persoon die de gegevens kent.

Vat dit bericht samen met: