TopicsCheat sheetLessons
Lurndo › Topics › CASE

Learn SQL: CASE

Choosing with CASE

Sanne wants an overview with labels: thin or thick, on time or late, Dutch or English. Those labels aren't anywhere in the database. You make them.

CASE chooses per row

CASE works like a series of if-thens: WHEN condition THEN value, and ELSE for the rest. It always ends with END. With AS you give the new column a name.

The first WHEN that holds wins. The others aren't even looked at.

SELECT title, pages, CASE WHEN pages < 200 THEN 'thin' WHEN pages < 400 THEN 'medium' ELSE 'thick' END AS thickness FROM books
Result
titlepagesthickness
De stille rivier312medium
Nachtwacht in Brugge288medium
Het laatste licht401thick
Draken van het Noorden624thick
Koken met restjes176thin
The Glass Harbour352medium
Zomer in Zeeland256medium
De code van Mercator336medium

Handle NULL first

A comparison with NULL is never true. So a book that is still out falls through every WHEN with < or > and ends up in the ELSE.

That's why you put the WHEN ... IS NULL first: then every row gets the right label.

SELECT id, due_on, returned_on, CASE WHEN returned_on IS NULL THEN 'still out' WHEN returned_on > due_on THEN 'late' ELSE 'on time' END AS status FROM loans
Result
iddue_onreturned_onstatus
12024-11-252024-11-22on time
22024-12-232024-12-27late
32025-01-292025-01-22on time
42025-02-102025-02-19late
52025-02-242025-02-24on time
62025-03-082025-02-24on time
72025-03-222025-03-21on time
82025-04-022025-04-26late

COALESCE, a short CASE for NULL

If all you want is a fallback value for NULL, COALESCE is shorter. COALESCE(email, 'no email') is the same as CASE WHEN email IS NULL THEN 'no email' ELSE email END.

You can give several values: COALESCE takes the first one that isn't NULL.

SELECT TRIM(name) AS name, COALESCE(email, 'no email') AS email FROM members
Result
nameemail
Sanne Willemssanne.willems@mail.be
Jef WoutersJef.Wouters@Mail.be
Amira El Idrissiamira.elidrissi@mail.be
Pieter Desmetpieter.desmet@mail.be
Lotte VandammeLOTTE.VANDAMME@MAIL.BE
Bert Claeysno email
Nina De Clercqnina.declercq@mail.be
Hamid Benalihamid.benali@mail.be

Counting with CASE

CASE can also go inside a function. SUM(CASE WHEN ... THEN 1 ELSE 0 END) counts per group how many rows meet a condition: every row that matches counts for 1.

That way you get the total and a part of it in one query.

SELECT LOWER(genre) AS genre, COUNT(*) AS books, SUM(CASE WHEN language = 'en' THEN 1 ELSE 0 END) AS in_english FROM books GROUP BY LOWER(genre)
Result
genrebooksin_english
comic20
fantasy30
non-fiction30
novel71
thriller51

Try it yourself

Show per member (member_id) how many loans came back late, and how many loans the member had in total.

Ready for more?

The full lesson has 6 exercises, from easy to challenging, with hints, points and a streak you can build.

Start the lesson
← PreviousCalculating with datesNext →A question inside a question
SQL topicsCheat sheetExcelLeaderboardAccountPrivacyNederlands