Du har brukt GROUP BY og COUNT for å telle antall sanger per album. Nå vil du bare se albumene som har nøyaktig 10 sanger. Du prøver å legge betingelsen i WHERE, men det fungerer ikke. WHERE filtrerer rader før gruppering. Du trenger noe som filtrerer etter gruppering. Det er HAVING.
HAVING er WHERE for grupper. Den filtrerer resultatet av aggregatfunksjoner som COUNT, SUM, AVG, MAX og MIN. Uten HAVING kan du gruppere og beregne, men du kan ikke stille krav til resultatene.
Hvorfor WHERE ikke fungerer
Forskjellen mellom WHERE og HAVING handler om tidspunkt. WHERE filtrerer individuelle rader før grupperingen skjer. HAVING filtrerer grupper etter at aggregeringen er ferdig.
Denne spørringen gir feilmelding:
SELECT album_id, COUNT(*) FROM tracks WHERE COUNT(*) = 10 GROUP BY album_id;
Feilen er at COUNT(*) ikke finnes ennå når WHERE kjører. Radene er ikke gruppert ennå, så det finnes ingenting å telle. Du må bruke HAVING i stedet:
SELECT album_id, COUNT(*) FROM tracks GROUP BY album_id HAVING COUNT(*) = 10;
Nå grupperer SQL først alle sangene per album, teller dem, og fjerner deretter gruppene som ikke har nøyaktig 10 sanger.
HAVING med COUNT
Den vanligste bruken av HAVING er å filtrere på antall. For eksempel: finn byer med mer enn én kunde.
SELECT city, COUNT(*) AS antall FROM customers GROUP BY city HAVING COUNT(*) > 1;
Resultatet viser bare byer der det finnes to eller flere kunder. Byer med bare én kunde blir filtrert bort. Legg merke til at du kan bruke AS for å gi kolonnen et lesbart navn, men i HAVING-betingelsen må du gjenta aggregatfunksjonen (COUNT(*) > 1), ikke aliaset.
HAVING med SUM
HAVING fungerer med alle aggregatfunksjoner. Si at du vil finne kunder som har handlet for mer enn 40 totalt:
SELECT customer_id, SUM(total) AS total_spent FROM invoices GROUP BY customer_id HAVING SUM(total) > 40;
Her summerer SQL totalbeløpet for hver kunde, og filtrerer bort de som har handlet for 40 eller mindre. Resultatet gir deg bare storkunder.
HAVING med MAX og MIN
Du kan også filtrere på høyeste eller laveste verdi i en gruppe:
SELECT customer_id, MAX(total) AS storste_faktura FROM invoices GROUP BY customer_id HAVING MAX(total) > 20;
Denne finner kunder som har minst én faktura over 20. MAX(total) gir den høyeste fakturaverdien per kunde, og HAVING beholder bare gruppene der denne verdien overstiger 20.
Kombinere WHERE og HAVING
WHERE og HAVING utelukker ikke hverandre. Du kan bruke begge i samme spørring, og de har ulike oppgaver:
SELECT customer_id, COUNT(*) AS antall FROM invoices WHERE invoice_date > '2023-01-01' GROUP BY customer_id HAVING COUNT(*) >= 5;
Steg for steg: WHERE filtrerer først bort fakturaer fra før 2023. Deretter grupperer GROUP BY de gjenværende radene per kunde. Til slutt fjerner HAVING alle kunder med færre enn 5 fakturaer i perioden.
Tommelregel: bruk WHERE for betingelser på individuelle rader (kolonneverdier), og HAVING for betingelser på grupper (aggregerte verdier).
Rekkefølgen i spørringen
HAVING plasseres etter GROUP BY og før ORDER BY:
- SELECT
- FROM
- WHERE (filtrerer rader)
- GROUP BY (grupperer)
- HAVING (filtrerer grupper)
- ORDER BY (sorterer)
En komplett spørring kan se slik ut:
SELECT country, COUNT(*) AS antall FROM customers WHERE country != 'USA' GROUP BY country HAVING COUNT(*) >= 2 ORDER BY antall DESC;
Denne utelukker amerikanske kunder, grupperer resten etter land, beholder land med minst 2 kunder, og sorterer resultatet etter antall i synkende rekkefølge.
Praktisk eksempel: finn storkunder
HAVING er spesielt nyttig i rapportering. Si at du vil finne landene der gjennomsnittsfakturaen er over 6:
SELECT billing_country, AVG(total) AS snitt FROM invoices GROUP BY billing_country HAVING AVG(total) > 6 ORDER BY snitt DESC;
Denne spørringen grupperer fakturaer per land, beregner gjennomsnittlig totalbeløp, filtrerer bort land under terskelen, og sorterer de gjenværende landene etter gjennomsnitt. Det er en kompakt måte å få innsikt i hvilke markeder som har de høyeste verdiene.
HAVING uten GROUP BY
Teknisk sett kan du bruke HAVING uten GROUP BY. Da behandler SQL hele resultatet som én gruppe:
SELECT COUNT(*) FROM invoices HAVING COUNT(*) > 100;
Denne returnerer det totale antallet fakturaer, men bare hvis det er over 100. Ellers returnerer spørringen ingenting. I praksis er dette sjelden nyttig, men det er greit å vite at det er mulig.
Vanlige feil med HAVING
- Bruke WHERE i stedet for HAVING. Aggregatfunksjoner som COUNT og SUM kan ikke brukes i WHERE. Bruker du dem der, får du feilmelding.
- Referere til alias i HAVING. De fleste databaser krever at du gjentar aggregatfunksjonen i HAVING (for eksempel HAVING COUNT(*) > 5), ikke aliaset (HAVING antall > 5). SQLite tillater alias i HAVING, men det er ikke portabelt.
- Glemme GROUP BY. HAVING gir mest mening sammen med GROUP BY. Uten gruppering har du bare én samlet «gruppe» å filtrere på.
Neste steg
Med GROUP BY og HAVING kan du gruppere data og stille krav til gruppene. For å forstå aggregering fullt ut, bør du også lære hvordan NULL-verdier påvirker beregningene dine. Og når du trenger data fra flere tabeller, er JOIN neste steg.
Denne videoen er hentet fra kurset SQL for nybegynnere på Utdannet.no. I kurset jobber du med praktiske eksempler og lærer SQL steg for steg.



