Så använder du CASE i SQL utan oväntade resultat

15 oktober 2026

Person söker en omfattande guide till SQL CASE WHEN-satser, med kugghjul som symboliserar databashantering.

När en webbshop ska märka order som ”liten”, ”normal” eller ”stor” kan SQL göra jobbet direkt i frågeresultatet. CASE passar oftast när en fråga ska ge olika värden beroende på villkor, men utfallet påverkas av ordningen på villkoren och hur NULL hanteras.

CASE gör villkor till värden i frågeresultatet

  • Två former: enkel CASE för likhetsjämförelser och sökt CASE för villkor som intervall.
  • Första träffen gäller: villkoren prövas i ordning, så placera de mest specifika först.
  • ELSE saknas: om inget villkor matchar blir resultatet normalt NULL.
  • Datatyper måste fungera ihop: resultatgrenarna behöver kunna förenas till en gemensam typ.

Välj sökt CASE när villkoret handlar om mer än likhet

En order på 1 200 kronor kan hamna i en annan kategori än en order på 300 kronor, trots att båda ligger i samma kolumn. Därför tycker jag att sökt CASE är det tydligaste valet när logiken bygger på intervall eller flera jämförelser.

Den sökta formen utgår från ett eller flera villkor. Varje WHEN testar en logisk uttrycksdel, och motsvarande THEN anger värdet som ska returneras:

SELECT
    order_id,
    total_amount,
    CASE
        WHEN total_amount >= 1000 THEN 'Stor'
        WHEN total_amount >= 300 THEN 'Normal'
        ELSE 'Liten'
    END AS orderstorlek
FROM orders;

Här hamnar en order på 1 200 i kategorin ”Stor”. En order på 500 blir ”Normal”. Eftersom villkoren prövas uppifrån och den första sanna grenen väljs, ska gränsen 1 000 stå före gränsen 300.

Enkel CASE är renare när du bara jämför värden

Om en kolumn bara ska översättas från fasta koder till begripliga etiketter blir enkel CASE ofta mer lättläst. Tänk på en webbplats där statuskoder ska visas som text:

SELECT
    order_id,
    CASE status
        WHEN 'new' THEN 'Ny'
        WHEN 'paid' THEN 'Betald'
        WHEN 'sent' THEN 'Skickad'
        ELSE 'Okänd status'
    END AS status_text
FROM orders;

Den här formen jämför uttrycket efter CASE med varje värde efter WHEN. Den passar för likhet, men inte för exempelvis ”större än” eller ett beloppsintervall. I sådana fall väljer du sökt CASE, som beskrivs i PostgreSQLs dokumentation om villkorsuttryck.

Villkorsordningen avgör vilken kategori som visas

Två villkor kan passa samma rad, men bara det första matchande resultatet används. Det låter enkelt tills en bred regel råkar ligga före en smalare.

Anta att ”premium” ska gälla för kunder med minst tio köp, medan ”kund” gäller för alla med minst ett köp. Om den breda regeln står först kan premiumkunder få etiketten ”kund”. Lägg därför mer avgränsade villkor före mer generella.

Situation Trolig följd Gör så här
En bred gräns står före en högre gräns Den breda grenen fångar även värden som skulle ha fått en mer specifik etikett. Flytta den snävare gränsen högre upp.
Inget villkor matchar och ELSE saknas Resultatet blir NULL, vilket kan ge tomma etiketter eller oväntade grupper. Lägg till ELSE om varje rad ska få ett synligt standardvärde.
En kolumn kan innehålla NULL En vanlig jämförelse med NULL blir inte sann. Testa uttryckligen med IS NULL i sökt CASE.
THEN- och ELSE-grenar returnerar oförenliga datatyper Databasen kan försöka konvertera värden eller ge ett fel. Se till att grenarna ger kompatibla typer, till exempel enbart text eller enbart numeriska värden.

Den där NULL-raden är lätt att missa. Skriv exempelvis WHEN status IS NULL THEN 'Saknas', inte WHEN status = NULL. SQL behandlar NULL som ett okänt värde, så en vanlig likhetsjämförelse fångar det inte.

CASE väljer ett värde, inte nästa SQL-åtgärd

Namnet ”CASE statement” används ofta i vardagligt tal, men i vanliga SQL-frågor är CASE ett uttryck som returnerar ett värde. Det kan därför passa i SELECT, ORDER BY och andra sammanhang där ett uttryck är tillåtet, men det ersätter inte ett procedurflöde som kör olika satser.

Det är en användbar skillnad när en fråga växer. CASE kan till exempel välja vilken etikett en rad får eller vilken sorteringsprioritet som visas. Om du behöver köra olika block med SQL-kod beroende på villkor ska du i stället använda det procedurspråk som databasen erbjuder. Microsoft beskriver samma gräns för CASE i Transact-SQL.

Gör resultatet förutsägbart med ELSE och gemensamma typer

En kategori som ibland blir tom är ofta en följd av att CASE saknar ELSE. När ingen WHEN matchar returneras NULL om ingen standardgren har angetts. Jag tycker att ett uttryckligt ELSE är säkrast när rapporter, etiketter eller grupper ska vara begripliga även för oväntade värden.

Grenarnas resultat behöver också kunna bli en gemensam datatyp. Blanda exempelvis inte en textetikett i en gren med ett datum i en annan och räkna med att varje databasmotor tolkar det likadant. Om CASE ger ett fel eller konstiga konverteringar, kontrollera först datatyperna i THEN och ELSE.

Det finns dessutom en viktig gräns för kortslutning: även om CASE testar villkor i ordning ska du inte använda den som skydd mot varje beräkningsfel. SQL Server dokumenterar att vissa uttryck, bland annat aggregat i WHEN-villkor, kan beräknas innan CASE-villkoret utvärderas. Bygg därför inte säkerheten i en riskfylld beräkning på antagandet att en tidigare gren alltid stoppar den.

En bra CASE börjar med rätt fråga om varje rad

Föreställ dig en rapport som ska sortera order efter belopp, men där saknade belopp också måste synas. Börja med att bestämma vad NULL ska betyda, lägg sedan de högsta och mest specifika gränserna först och avsluta med en ELSE som beskriver återstående fall.

När utfallet fortfarande överraskar är det ofta enklare att tillfälligt visa både originalkolumnen och CASE-resultatet i samma SELECT. Då ser du exakt vilken rad som fångas av fel villkor, i stället för att gissa utifrån den färdiga etiketten.

Vanliga frågor

Använd sökt CASE när villkoren gäller intervall eller jämförelser, till exempel när orderbelopp ska delas in i kategorier. Enkel CASE passar när en kolumn jämförs med fasta värden, som statuskoderna 'new', 'paid' och 'sent'.
SQL väljer resultatet från den första matchande grenen. Om du exempelvis testar att beloppet är minst 300 före att det är minst 1 000 kan även stora order få kategorin 'Normal'. Placera därför det mest specifika eller högsta gränsvillkoret först.
Om inget WHEN-villkor matchar och ELSE saknas blir resultatet normalt NULL. En vanlig jämförelse som status = NULL fångar inte heller NULL-värden, så använd i sökt CASE villkoret status IS NULL och lägg till ELSE om du vill ange ett standardvärde.
THEN- och ELSE-grenarna måste ge värden som kan förenas till en gemensam datatyp. Håll exempelvis grenarna till enbart text eller enbart numeriska värden, annars kan databasen försöka konvertera värden eller ge ett fel.
Betygsätt artikeln

Genomsnitt: 0.0 / 5 · 0 betyg

Taggar

null-värden case-uttryck datatyper villkorslogik
Kommentarer (0)
Lägg till en kommentar