HAVING kontra WHERE
Filtrering før kontra efter gruppering, og hvilken klausul der kan se aggregatet
HAVING kontra WHERE er en gratis Forberedelse til SQL-interview-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Forberedelse til SQL-interview, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Forberedelse til SQL-interview-kurset indeholder 4 lektioner i alt.
Spørgsmålet, du får
'Hvad er forskellen på WHERE og HAVING?' er et af de hyppigst stillede SQL-spørgsmål ved jobsamtaler. Et svagt svar siger 'HAVING er til aggregater.' Et stærkt svar forklarer hvornår hver klausul udføres i forespørgslens behandlingsforløb.
Det hele handler om tidspunktet: WHERE filtrerer rækker før gruppering, mens HAVING filtrerer grupper efter aggregering.
Hvor de ligger i udførelsesrækkefølgen
Husk den logiske udførelsesrækkefølge for en forespørgsel:
FROM/JOIN→ opbygger rækkesættetWHERE→ filtrerer individuelle rækkerGROUP BY→ samler rækkerne i grupperHAVING→ filtrerer grupperneSELECT→ udvælger kolonnerORDER BY→ sorterer
WHERE udføres, før grupperne findes; HAVING udføres bagefter. Derfor kan HAVING se aggregater, mens WHERE ikke kan.
WHERE kan ikke se aggregater
Fordi WHERE udføres før gruppering, har den endnu ingen aggregatværdier. Det er en syntaksfejl i alle standarddatabaser at skrive WHERE COUNT(*) > 5.
Interviewere indsætter netop denne linje for at kontrollere, om du forstår behandlingsforløbet. Aggregatet findes ikke, når WHERE evalueres.
-- ERROR: aggregate not allowed in WHERE
SELECT department, COUNT(*)
FROM employees
WHERE COUNT(*) > 5
GROUP BY department;HAVING filtrerer grupperne
Flyt aggregatbetingelsen til HAVING, så virker det, fordi HAVING udføres, efter at grupperne og deres aggregater er beregnet.
Læs det sådan: 'Gruppér medarbejderne, og behold derefter kun afdelinger, hvis antal overstiger fem.'
SELECT department, COUNT(*) AS headcount
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;Placér rækkefiltre i WHERE
Den omvendte fejl er at filtrere rå rækker i HAVING. Det giver ofte det rigtige svar, men er langsommere og misvisende, fordi du grupperede rækker, som du havde tænkt dig at frasortere.
Tommelfingerregel: Filtrér efter en rå kolonneværdi → WHERE. Filtrér efter et aggregat → HAVING. Når du filtrerer rækker tidligt, bliver de data, som grupperingen skal behandle, mindre.
-- Better: drop inactive rows BEFORE grouping
SELECT department, COUNT(*) AS headcount
FROM employees
WHERE status = 'active'
GROUP BY department
HAVING COUNT(*) > 5;Begge klausuler sammen
En komplet forespørgsel bruger ofte begge. WHERE indsnævrer først rækkerne; derefter beholder HAVING de grupper, der opfylder betingelsen. At læse fra top til bund svarer til den logiske rækkefølge.
Gennemgået eksempel: Find de kunder, der i alt har brugt mere end 1000, blandt ordrer afgivet i år.
SELECT customer_id, SUM(amount) AS total_spent
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY customer_id
HAVING SUM(amount) > 1000;HAVING på ikke-aggregerede kolonner
HAVING kan referere til en grupperingskolonne, ikke kun til aggregater. HAVING department = 'Sales' er lovlig, men meningsløs: Det filter hører hjemme i WHERE, så det udføres tidligere.
Hvis en interviewer viser dig en HAVING, der filtrerer en almindelig grupperet kolonne, forventes det, at du siger: 'Flyt den til WHERE for at gøre forespørgslen mere effektiv.'
-- Works but inefficient; prefer WHERE department = 'Sales'
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING department = 'Sales';HAVING uden GROUP BY
En subtil detalje: HAVING er lovlig selv uden GROUP BY. Hele tabellen bliver til én implicit gruppe, og HAVING filtrerer denne ene gruppe.
Hvis aggregatbetingelsen er falsk, får du nul rækker; hvis den er sand, får du én række. Det er sjældent nyttigt, men interviewere spørger til det for at bekræfte, at du forstår begrebet implicit gruppe.
-- Returns the count only if the table has > 100 rows
SELECT COUNT(*) AS total
FROM orders
HAVING COUNT(*) > 100;Kan HAVING bruge et SELECT-alias?
Ligesom med aliasets rækkevidde andre steder er der forskel på SQL-dialekter. Postgres og MySQL lader HAVING referere til et SELECT-alias; SQL Server og Oracle gør ikke.
Den portabelle vane er at gentage aggregatudtrykket i HAVING. Det virker i alle databasemotorer og undgår overraskelser ved en jobsamtale på tværs af databaser.
-- Portable: repeat the aggregate, do not rely on the alias
SELECT region, SUM(amount) AS total
FROM sales
GROUP BY region
HAVING SUM(amount) > 5000;Præstationsperspektivet
Hvis du vil imponere, skal du koble klausulerne til ydeevne: WHERE reducerer antallet af rækker, som grupperingsmotoren skal gennemgå, og kan bruge indeks; HAVING udføres på allerede aggregerede grupper og kan derfor ikke reducere omkostningerne ved grupperingen.
Det, interviewerne vil høre, er: Skub hvert filter så tidligt som muligt. Kun betingelser, der reelt afhænger af et aggregat, har brug for HAVING.
Svaret i én sætning
Lær dette udenad til jobsamtalen: 'WHERE filtrerer rækker før gruppering og kan ikke se aggregater; HAVING filtrerer grupper efter aggregering og er den eneste klausul, der kan teste en aggregatværdi.'
Følg det op med listen over udførelsesrækkefølgen, så har du givet et komplet svar, der lyder som et svar fra en erfaren udvikler.
Hurtigt tjek
Find ud af, hvilken klausul hver betingelse hører hjemme i.
Opsummering
WHERE: filtrerer rækker før GROUP BY; aggregater er ikke tilladt. HAVING: filtrerer grupper efter aggregering og er det eneste sted, hvor en aggregatbetingelse er lovlig.
- Placér filtre på rå kolonner i WHERE for at opnå bedre hastighed og udnytte indeks.
- HAVING kan referere til grupperede kolonner, men bør ikke bruges til almindelige filtre.
- HAVING fungerer uden GROUP BY på den implicitte gruppe, der består af hele tabellen.
- Gentag aggregatudtryk i HAVING for at sikre kompatibilitet på tværs af dialekter.
Lær SQL med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “HAVING kontra WHERE” gratis?
Ja — hele teksten til “HAVING kontra WHERE” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Forberedelse til SQL-interview-kurset, skal du opgradere til CoddyKit PRO. Forberedelse til SQL-interview-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “HAVING kontra WHERE”?
Filtrering før kontra efter gruppering, og hvilken klausul der kan se aggregatet Du øver dig i Forberedelse til SQL-interview med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Forberedelse til SQL-interview?
Der kræves ingen tidligere erfaring. Forberedelse til SQL-interview på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “HAVING kontra WHERE”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Forberedelse til SQL-interview-lektion?
Ja. Alle Forberedelse til SQL-interview-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- GROUP BY-reglen for SELECT-kolonner
- HAVING kontra WHERE
- Gruppering efter flere kolonner og udtryk
- Optælling og filtrering af grupper