GROUP BY i SQL: så får du rätt sammanställning

3 november 2026

SQL-kod visar hur man använder `sql group by` med ROLLUP för att summera försäljning per produkt, månad och år. Resultatet visas i en tabell.

När du vill se vilka sidor som får flest besök räcker råa analysrader sällan långt. Med GROUP BY kan du samla rader med samma värde och räkna eller summera dem, men resultatet beror på vilka kolumner du grupperar efter.

Gruppera rätt för att få användbara sammanställningar

  • En rad per grupp: välj grupperingskolumnen och ett aggregat som COUNT eller SUM.
  • Filtrera före och efter: WHERE tar bort rader före grupperingen, medan HAVING filtrerar färdiga grupper.
  • Flera kolumner ger en grupp för varje unik kombination av värden.
  • Kontrollera JOIN-resultatet: en koppling kan mångdubbla rader och därmed blåsa upp summor.
  • Undvik otydliga kolumner: välj bara grupperade kolumner och aggregat, så blir frågan tydligare mellan databaser.

En grupp motsvarar en rad i resultatet

Tänk dig en tabell med webbplatsbesök där varje rad är en sidvisning. Om du vill räkna sidvisningar per sida grupperar du på sidans namn och låter COUNT räkna raderna i varje grupp.

SELECT page_path, COUNT(*) AS visits
FROM pageviews
GROUP BY page_path
ORDER BY visits DESC;

Resultatet innehåller en rad per unikt värde i page_path. COUNT(*) räknar alla rader i gruppen, medan exempelvis SUM(revenue) summerar värden och AVG(load_time) beräknar ett genomsnitt. Jag tycker att det blir lättare att granska resultatet när varje vald kolumn antingen står i GROUP BY eller används i ett aggregat.

WHERE och HAVING filtrerar vid olika tillfällen

En rapport kan ge rätt totalsumma men ändå svara på fel fråga om filtret hamnar på fel ställe. WHERE väljer vilka rader som får delta i grupperingen; HAVING väljer vilka grupper som ska finnas kvar efter att aggregaten räknats fram.

SELECT page_path, COUNT(*) AS visits
FROM pageviews
WHERE visited_at >= '2026-01-01'
GROUP BY page_path
HAVING COUNT(*) >= 100
ORDER BY visits DESC;
Här tas äldre sidvisningar bort före beräkningen, och därefter visas bara sidor med minst 100 besök under perioden. En praktisk tumregel är enkel: filtrerar du enskilda poster, börja med WHERE; filtrerar du på ett beräknat gruppresultat, använd HAVING. PostgreSQLs dokumentation om GROUP BY och HAVING beskriver samma skillnad i frågans bearbetning.

Flera grupperingskolumner delar upp resultatet mer

Om trafiken ska delas upp både per sida och enhetstyp lägger du till båda kolumnerna i grupperingen. Då blir varje unik kombination en egen grupp, exempelvis startsida plus mobil eller startsida plus dator.

SELECT page_path, device_type, COUNT(*) AS visits
FROM pageviews
GROUP BY page_path, device_type
ORDER BY page_path, device_type;

Det här kan avslöja att en sida fungerar väl på dator men får få besök från mobil. Samtidigt blir resultatet mer uppdelat: varje extra grupperingskolumn kan skapa fler rader och mindre underlag per grupp. Om du bara behöver en lista över unika sidnamn kan SELECT DISTINCT page_path vara tydligare än GROUP BY page_path utan aggregat.

NULL och JOIN kan ge oväntade gruppresultat

En tom kategori försvinner inte automatiskt ur resultatet. Databasens grupperingsbeteende samlar NULL-värden i en grupp, så du kan få en rad där kategorin saknas. Det kan vara en användbar signal om spårningen inte skickar in värdet, snarare än en kategori att ignorera.

En annan fallgrop uppstår när tabeller kopplas ihop. Anta att en orderrad på 100 kronor matchar två kampanjrader: efter kopplingen förekommer orderraden två gånger, och en efterföljande SUM kan räkna 200 kronor. Kontrollera därför hur många matchningar varje rad får innan du summerar, eller aggregera orderraderna i en undertabell före kopplingen.

SituationTrolig orsak eller följdGör så här
En extra rad har tom kategoriGrupperingskolumnen innehåller NULLKontrollera källdatan; använd vid behov COALESCE för en tydlig etikett.
Summan efter en JOIN är för högEn rad matchar flera rader i den andra tabellenGranska matchningsantalet och aggregera på rätt nivå före kopplingen.
Frågan ger fel för en vald kolumnKolumnen är varken grupperad eller aggregeradLägg till den i GROUP BY eller välj ett aggregat som passar frågan.

Databasmotorn kan avgöra om frågan godkänns

En fråga som fungerar i en databas kan stoppas av en annan, särskilt om SELECT innehåller en kolumn som inte grupperas. MySQL 8.4 med läget ONLY_FULL_GROUP_BY aktiverat avvisar normalt sådana otydliga val om kolumnen inte bestäms av grupperingskolumnerna; utan läget kan MySQL välja ett godtyckligt värde från gruppen. MySQL 8.4 Reference Manual beskriver både begränsningen och varför ett sådant värde kan bli icke-deterministiskt.

SQL Server kräver att kolumner som används i icke-aggregerade uttryck i urvalet finns med i grupperingen. Microsofts dokumentation om GROUP BY i Transact-SQL anger också att grupperingen kan omfatta uttryck och erbjuder tillägg som ROLLUP för delsummor. För frågor som ska flyttas mellan motorer är därför den säkraste vanan att hålla urvalet tydligt och undvika icke-aggregerade kolumner utanför grupperingen.

En tydlig gruppering ger mer pålitliga rapporter

När en sammanställning ser märklig ut, kontrollera först gruppnycklarna, därefter filtren och till sist om en JOIN har duplicerat rader. Den ordningen brukar snabbt skilja ett grupperingsfel från ett problem i källdatan.

För en rapport över webbtrafik betyder det att du först bestämmer nivån, exempelvis sida eller sida och enhet, och sedan väljer ett aggregat som verkligen beskriver den nivån. Då blir varje resultat rad för rad begripligt, även när analysen växer.

Vanliga frågor

WHERE filtrerar enskilda rader innan grupperingen och aggregaten beräknas. HAVING filtrerar grupper efteråt, till exempel med HAVING COUNT(*) >= 100 för att bara visa sidor med minst 100 besök.
Ta med både page_path och device_type i GROUP BY och använd exempelvis COUNT(*). Då får du en rad per unik kombination av sida och enhetstyp, såsom startsida och mobil.
En rad från den ena tabellen kan matcha flera rader i den andra och därmed förekomma flera gånger efter kopplingen. En orderrad på 100 kronor som matchar två kampanjrader kan därför räknas som 200 kronor. Kontrollera antalet matchningar eller aggregera orderraderna före kopplingen.
Rader med NULL i grupperingskolumnen samlas i en egen grupp, så resultatet kan innehålla en rad där kategorin saknas. Kontrollera källdatan och använd vid behov COALESCE för att visa en tydlig etikett.
Betygsätt artikeln

Genomsnitt: 0.0 / 5 · 0 betyg

Taggar

having join group by aggregatfunktioner null-värden
Kommentarer (0)
Lägg till en kommentar