Inleiding tot SQL HEBT clausule

De zeer fundamentele vraag die in de geest opkomt, is wat is deze clausule? Welnu, de HAVING-clausule wordt gebruikt om de resultaten van een SQL-query met geaggregeerde functies uit te filteren. Om het in gewoon Engels te begrijpen, beveelt het de SQL-parser 'Hey SQL, haal me uit onze tabel met klantgegevens de namen van landen met meer dan 1 miljoen klanten'.

Wacht, dat is wat de WHERE-clausule doet, niet? Ja, dat lijkt erg op de werking van de WHERE-clausule, maar met een klein verschil. De WHERE-clausule werkt niet met geaggregeerde functies.

Om het nog wat kort te houden over geaggregeerde functies, dit zijn functies die meerdere rijen als invoer gebruiken en een meer verwerkte uitvoer opleveren. Enkele voorbeelden zijn Count (), Sum (), Min (), Max (), Avg () etc.

Waarom HEBBEN en niet WAAR?

We zien dat clausules HAVING en WHERE een zeer vergelijkbare taak uitvoeren om de resultaten uit te filteren. Wat was dan de behoefte aan de clausule HAVING? Waarom kan de WHERE-clausule niet worden gebruikt met geaggregeerde functies?

Om dit te beantwoorden, zouden we moeten begrijpen hoe de SQL-engine de twee clausules behandelt. De clausule FROM in elke SQL-opdracht vertelt de engine waar de rijen moeten worden gelezen. De gegevens worden op de schijf opgeslagen en voor verwerking in het geheugen opgehaald. Omdat de rijen één voor één worden gelezen van de schijf naar het geheugen, worden ze gecontroleerd op de WHERE-component. De rijen die niet voldoen aan de WHERE-component worden niet in het geheugen geladen. De WHERE-component wordt dus geëvalueerd voor elke rij terwijl deze wordt verwerkt door de SQL-engine.

Integendeel, de clausule HAVING komt pas in beeld nadat de rijen in het geheugen zijn geladen. Eenmaal in het geheugen geladen, voeren de aggregatiefuncties hun taak uit op de rijen met de gewenste voorwaarde.

Als we nu een WHERE-clausule zouden plaatsen met de aggregatiefunctie zoals avg (), zou dit de SQL-engine verwarren over het al dan niet opnemen van de rij voor het berekenen van het gemiddelde. In wezen zouden we de motor opdracht geven de rij niet te lezen, omdat deze niet aan de criteria avg () in de clausule WHERE heeft voldaan. Maar ja, om te bepalen of de berekeningscriteria van avg () zijn geslaagd of niet, moet de rij in het geheugen worden gelezen. Een impasse.

De syntaxis

SELECT
FROM


WAAR - optioneel
GROEPEN OP - groepeert de rijen om de aggregatiefunctie toe te passen
HEBBEN - geaggregeerde functie in de voorwaarde
BESTELLEN BIJ; - definieer de sorteervolgorde, optioneel

Opmerking - De clausule GROUP BY is vereist bij de clausule HAVING. Dit komt omdat Have-component een groep gegevens nodig heeft om een ​​aggregatiefunctie toe te passen en de resultaten eruit te filteren.

Hoe HAVING-clausule werkt?

Laten we de werking van de HAVING-clausule in SQL begrijpen.

De clausule HAVING gaat altijd vergezeld van de clausule GROUP BY. De clausule GROUP BY groepeert de gegevens die aan een bepaald criterium voldoen. Het heeft drie fasen - splitsen, toepassen en combineren. De split-fase verdeelt de rijen in groepen. De fase Toepassen past enkele geaggregeerde functies toe op de groepen gegevens. De gecombineerde fase levert een enkel resultaat op door de groepen te combineren met het resultaat van de aggregatiefunctie.

Nu de groepen zijn gevormd, komt de HAVING-clausule in beeld. De clausule HAVING filtert vervolgens de groepen uit die niet aan de gegeven voorwaarde voldoen.

SELECT Col_A, avg(Col_B) as Col_B
FROM MyTable
GROUP BY Col_A
HAVING avg(Col_B)>30

In het bovenstaande voorbeeld zien we dus dat de tabel eerst wordt gesplitst in drie groepen op basis van de kolom Col_A. De aggregatiefunctie om het gemiddelde van Col_B-waarden te berekenen, wordt vervolgens op de groepen toegepast. Dit resulteert in een enkele rij voor elke groep. De rijen worden vervolgens gecombineerd en gefilterd op basis van de voorwaarde in de clausule HAVING.

Voorbeeld

Laten we nu eens kijken naar een voorbeeld uit de echte wereld. Overweeg dat we de volgende tabel met klanten hebben en de bestellingen die ze bij ons hebben geplaatst.

Klanten IDKlantnaamstadland
1Anja DamianBerlijnDuitsland
2Denny CockettMéxico DFMexico
3Eleanor CalnanMéxico DFMexico
4Albertha AlburyLondenUK
5Latisha NembhardLuleåZweden
6Madalene BingMannheimDuitsland
7Rebecka BeegleStraatsburgFrankrijk
8Rosy TippieMadridSpanje
9Audie KhanMarseilleFrankrijk
10Hildegard BurrowesTsawassenCanada
11Cordell DutrembleLondenUK
12Nora ReynaBuenos AiresArgentinië
13Ursula LaforestMéxico DFMexico
14Claudie NeelBernZwitserland
15Portia YeeSão PauloBrazilië
16Angila SegarraLondenUK
17Lise WexlerAachenDuitsland
18Ned MendivilNantesFrankrijk
19Sara VidaurriLondenUK
20Tayna NavinGrazOostenrijk
21Pura RaySão PauloBrazilië
22Erika ByardMadridSpanje
23Jimmie LukeLilleFrankrijk
24Shayla ByingtonBräckeZweden
25Christiana BodenMünchenDuitsland
26Irina NittaNantesFrankrijk
27Bryanna AllsTorinoItalië
28Norah PickenLisboaPortugal
29Moriah StwartBarcelonaSpanje
30Idella HarriottSevillaSpanje
Order IDKlanten IDBesteldatum
10254141996/11/07
102582017-07-1996
102591318-07-1996
102632023-07-1996
102642424-07-1996
10265725-07-1996
102672529-07-1996
1027851996/12/08
10280514-08-1996
102891126-08-1996
102901527-08-1996
1029771996/04/09
10303301996/11/09
10308218-09-1996
103111820-09-1996
1032681996/10/10
10327241996/11/10
103282814-10-1996
10331916-10-1996
103372524-10-1996
10340929-10-1996
103422530-10-1996
10347211996/06/11
10351201996/11/11
10352281996/12/11
10355415-11-1996
10360722-11-1996
10362925-11-1996
103631726-11-1996
103641926-11-1996
10365327-11-1996
103662928-11-1996
103682029-11-1996
10370141996/03/12
10378241996/10/12
103822013-12-1996
10383416-12-1996
10384516-12-1996
103862118-12-1996
103891020-12-1996
103902023-12-1996
103911723-12-1996
103962527-12-1996
104001901-01-1997
10402201997/02/01
10403201997/03/01
10408231997/08/01
10410101997/10/01
10411101997/10/01
104142114-01-1997
104222722-01-1997
104262927-01-1997
104302030-01-1997
104311030-01-1997
10434241997/03/02
10435161997/04/02
1043671997/05/02
10442201997/11/02

Nu willen we klanten weten uit welke landen in totaal 5 of meer bestellingen bij ons hebben geplaatst. Het kan een enkele klant zijn die meer dan 5 bestellingen plaatst of 5 klanten die elk 1 bestelling plaatsen.

Om dit te bereiken, zouden we moeten

Stap 1 : Doe mee met de twee tafels

Stap 2: Groepeer de klanten op basis van hun land

Stap 3: Tel het aantal bestellingen voor elke groep

Stap 4: filter de resultaten voor 5 of meer bestellingen

Laten we het commando formuleren:

SELECT C.Country, COUNT(O.OrderId) as NumberOfOrders -- Step 1, 3
FROM Customers C -- Step 1
INNER JOIN Orders O on C.CustomerID = O.CustomerID -- Step 1
GROUP BY C.Country -- Step 2
HAVING COUNT(O.OrderId) >= 5 -- Step 4
ORDER BY COUNT(O.OrderId) DESC

Dit zijn de resultaten:

landAantal bestellingen
Oostenrijk10
Frankrijk9
Zweden7
Duitsland6
UK6

Conclusie - SQL-clausule

We hebben dus gezien wat het doel van de HAVING-clausule is en hoe het werkt. Het is belangrijk om de basiswerking te begrijpen, anders raakt u misschien in de war over waarom de HAVING-clausule niet de gewenste resultaten oplevert. Blijf spelen met verschillende tafels en joins en combinaties samen met de clausule HAVING.

Aanbevolen artikelen

Dit is een handleiding voor de SQL HAVING-clausule. Hier bespreken we de werking van de HAVING-clausule in SQL en een voorbeeld met de volgende tabel met klanten. U kunt ook onze andere voorgestelde artikelen doornemen -

  1. Query invoegen
  2. Buitenlandse sleutel in SQL
  3. Onderscheid sleutelwoord in SQL
  4. SQL-weergaven
  5. Top 6 Query-voorbeelden van Inner Join in Oracle