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
COUNTellerSUM. - Filtrera före och efter:
WHEREtar bort rader före grupperingen, medanHAVINGfiltrerar 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.
| Situation | Trolig orsak eller följd | Gör så här |
|---|---|---|
| En extra rad har tom kategori | Grupperingskolumnen innehåller NULL | Kontrollera källdatan; använd vid behov COALESCE för en tydlig etikett. |
| Summan efter en JOIN är för hög | En rad matchar flera rader i den andra tabellen | Granska matchningsantalet och aggregera på rätt nivå före kopplingen. |
| Frågan ger fel för en vald kolumn | Kolumnen är varken grupperad eller aggregerad | Lä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.