Aggregeringar per grupp utan GROUP BY
Använd en korrelerad underfråga för att beräkna gruppens maxvärde bredvid detaljrader
Aggregeringar per grupp utan GROUP BY är en gratis lektion i Förberedelser inför SQL-intervjun på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Förberedelser inför SQL-intervjun, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.
Problemet med detaljrader plus aggregat
En vanlig intervjufråga är: "Visa varje rad tillsammans med ett aggregat för dess grupp." Till exempel att lista varje anställd tillsammans med avdelningens högsta lön på samma rad.
Vanligt GROUP BY slår ihop rader, så det kan inte behålla detaljuppgifterna för varje anställd. Ni behöver både detaljraderna och ett tal på gruppnivå samtidigt.
En korrelerad underfråga löser detta elegant: den beräknar gruppens aggregat för varje detaljrad utan att slå ihop några rader.
Varför vanligt GROUP BY inte fungerar här
Om ni skriver SELECT dept_id, MAX(salary) FROM employees GROUP BY dept_id får ni en rad per avdelning och förlorar de individuella namnen.
Om ni lägger till name i SELECT utan att lägga till den i GROUP BY uppstår det klassiska felet "column must appear in GROUP BY".
Intervjuaren kontrollerar om ni förstår att GROUP BY minskar kardinaliteten. För att behålla detaljraderna måste ni beräkna aggregatet på ett annat sätt.
En korrelerad underfråga löser problemet
Placera gruppens aggregat i SELECT-listan som en korrelerad underfråga. Varje anställdrad utlöser ett inre MAX som begränsas till den anställdas avdelning.
Korrelationen e2.dept_id = e1.dept_id kopplar aggregatet till rätt grupp, samtidigt som den yttre frågan fortfarande returnerar en rad per anställd.
SELECT e1.name,
e1.dept_id,
e1.salary,
(SELECT MAX(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id) AS dept_max_salary
FROM employees e1;Jämför varje rad med dess grupp
När gruppens aggregat finns med i frågan kan ni jämföra varje rad med det. En vanlig fråga är: "Hitta anställda som tjänar mer än genomsnittet på sin avdelning."
Här finns det korrelerade AVG i WHERE, så varje anställd jämförs med genomsnittet för sin egen avdelning.
SELECT e1.name, e1.dept_id, e1.salary
FROM employees e1
WHERE e1.salary > (
SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id
);Beräkna skillnaden från gruppen
Ni kan också visa hur långt varje rad ligger från gruppens aggregat. Genom att subtrahera det korrelerade genomsnittet får ni en skillnad per rad.
Lägg märke till att samma korrelerade underfråga kan återanvändas i flera SELECT-uttryck. Motorn utvärderar den en gång per rad varje gång den förekommer.
SELECT e1.name,
e1.salary,
e1.salary - (SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id) AS gap_from_dept_avg
FROM employees e1;Hitta den högst avlönade per grupp
Om ni bara vill returnera den högst avlönade personen per avdelning jämför ni varje lön med det korrelerade MAX-värdet och behåller matchningarna.
Det här mönstret returnerar även lika resultat: om två anställda delar avdelningens maxlön visas båda. Den här hanteringen av lika resultat är ofta intervjuarens följdfråga.
SELECT e1.name, e1.dept_id, e1.salary
FROM employees e1
WHERE e1.salary = (
SELECT MAX(e2.salary)
FROM employees e2
WHERE e2.dept_id = e1.dept_id
);Alternativet med fönsterfunktioner
Modern SQL erbjuder ett renare verktyg: fönsterfunktioner. MAX(salary) OVER (PARTITION BY dept_id) beräknar gruppens aggregat utan att slå ihop rader och utan en korrelerad ny genomgång.
Intervjuare uppskattar när ni kan ta fram båda lösningarna och förklara att fönsterversionen vanligtvis presterar bättre eftersom den läser igenom tabellen en gång.
SELECT name,
dept_id,
salary,
MAX(salary) OVER (PARTITION BY dept_id) AS dept_max_salary
FROM employees;Avvägningar mellan korrelerade underfrågor och fönsterfunktioner
Båda angreppssätten returnerar samma struktur, men de skiljer sig åt:
- Korrelerad underfråga: portabel och fungerar i mycket gamla motorer, men utvärderas på nytt för varje rad.
- Fönsterfunktion: en enda genomgång, betydligt snabbare på stora tabeller, men kräver stöd för SQL-fönsterfunktioner.
Säg vilken ni skulle välja och varför. För en engångsfråga på en liten tabell fungerar båda bra, men för analys i stor skala bör ni föredra fönsterfunktionen.
Genomarbetat exempel: Order över kundens genomsnitt
Tillämpa mönstret på order. Visa order vars belopp överstiger kundens eget genomsnittliga ordervärde.
Det korrelerade AVG begränsas av o2.customer_id = o1.customer_id, vilket ger varje order kundens personliga jämförelsevärde.
SELECT o1.order_id, o1.customer_id, o1.amount
FROM orders o1
WHERE o1.amount > (
SELECT AVG(o2.amount)
FROM orders o2
WHERE o2.customer_id = o1.customer_id
);Var uppmärksam på NULL och tomma grupper
Om en grupp bara har en rad är dess genomsnitt lika med radens värde, så salary > avg är falskt och raden filtreras bort. Nämn detta specialfall på eget initiativ.
NULL-löner ignoreras dessutom av AVG och MAX, i enlighet med SQL:s aggregatsemantik. Om alla värden i en grupp är NULL blir aggregatet NULL och jämförelserna övergår till UNKNOWN, vilket gör att raden utesluts. Det är just förmågan att förutse sådana fall som skiljer ett grundligt svar från ett ytligt.
Räkna ut rangordningen inom en grupp
Ni kan uttrycka en rads rangordning inom gruppen med en korrelerad COUNT. För att hitta varje anställds lönerang inom avdelningen räknar ni hur många kollegor som tjänar mer.
Rang 1 betyder högst lön. Genom att lägga till 1 omvandlar ni antalet kollegor med högre lön till en position som börjar på 1, och korrelationen håller beräkningen inom avdelningen.
SELECT e1.name,
e1.dept_id,
e1.salary,
(SELECT COUNT(*) + 1
FROM employees e2
WHERE e2.dept_id = e1.dept_id
AND e2.salary > e1.salary) AS salary_rank_in_dept
FROM employees e1;Snabbtest
Välj anledningen till att en korrelerad underfråga är bättre än vanligt GROUP BY för den här uppgiften.
Sammanfattning: Aggregat per grupp utan GROUP BY
Viktiga slutsatser:
- En korrelerad underfråga placerar ett aggregat på gruppnivå på varje detaljrad utan att slå ihop raderna.
- Använd den i SELECT för att visa aggregatet eller i WHERE för att jämföra varje rad med sin grupp.
- Mönstret
= MAX(...)returnerar alla lika högt placerade topprader. - En fönsterfunktion med
PARTITION BYgör samma sak i en enda genomgång och skalar vanligtvis bättre.
Erbjud båda lösningarna och motivera ert val på intervjun.
Lär dig SQL med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Aggregeringar per grupp utan GROUP BY” gratis?
Ja – hela texten till ”Aggregeringar per grupp utan GROUP BY” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Förberedelser inför SQL-intervjun, kan Ni uppgradera till CoddyKit PRO. Kursen i Förberedelser inför SQL-intervjun innehåller totalt 4 lektioner.
Vad lär jag mig i ”Aggregeringar per grupp utan GROUP BY”?
Använd en korrelerad underfråga för att beräkna gruppens maxvärde bredvid detaljrader Ni övar på Förberedelser inför SQL-intervjun med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Förberedelser inför SQL-intervjun?
Du behöver inga förkunskaper. Utbildningen i Förberedelser inför SQL-intervjun på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Aggregeringar per grupp utan GROUP BY”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Förberedelser inför SQL-intervjun-lektionen?
Ja. Varje Förberedelser inför SQL-intervjun-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- En korrelerad underfrågas anatomi
- Aggregeringar per grupp utan GROUP BY
- Korrelerade EXISTS och NOT EXISTS
- Skriv om korrelerade underfrågor som joinar