datarekha

CASE expressions

SQL's if/else — conditional logic inside SELECT, ORDER BY, and aggregates. The Swiss-army knife you reach for constantly.

5 min read Beginner SQL Lesson 5 of 27

What you'll learn

  • Searched CASE versus simple CASE, and when to use each
  • Using CASE inside SELECT, ORDER BY, and aggregates
  • The conditional-sum trick that collapses five queries into one

Before you start

CASE is SQL’s if/else. Anywhere a column or expression can go — inside SELECT, WHERE, ORDER BY, even inside an aggregate — you can drop a CASE, which is what makes it one of the most versatile tools in the language.

It comes in two forms. Searched CASE takes full boolean conditions, top to bottom, and the first match wins:

CASE
  WHEN price < 5  THEN 'cheap'
  WHEN price < 20 THEN 'mid'
  ELSE                 'premium'
END

Simple CASE compares one value against a list (CASE category WHEN 'Stationery' THEN … END). Either way, if no branch matches and there is no ELSE, the result is NULL — so always think about the unmatched rows. The “first match wins, top to bottom” rule is the key thing to picture:

price = 12WHEN price < 5✗ false — skipWHEN price < 20✓ true’mid’ELSEnever reached

Each WHEN is checked top to bottom — the first match wins and the rest are skipped.

CASE in SELECT — a derived column

Bucket each product into a price tier:

SELECT name, price,
       CASE
         WHEN price < 5  THEN 'cheap'
         WHEN price < 20 THEN 'mid'
         ELSE                 'premium'
       END AS tier
FROM   products
ORDER BY price;
namepricetier
Pencil2cheap
Notebook6mid
Coffee9mid
Cable12mid
Laptop900premium

The same CASE works inside ORDER BY when you need a custom sort that is not alphabetical — ORDER BY CASE category WHEN 'Electronics' THEN 1 WHEN 'Grocery' THEN 2 ELSE 3 END puts your business priority first.

CASE inside an aggregate — the conditional sum

Here is the move that replaces five queries with one. Put a CASE inside SUM and you can count several different conditions side by side in a single pass. Take a small orders table:

order_idcountryqty
1IN1
2IN3
3US2
4US5
SELECT country,
       COUNT(*)                                    AS total_orders,
       SUM(CASE WHEN qty = 1  THEN 1 ELSE 0 END)   AS single_item,
       SUM(CASE WHEN qty >= 3 THEN 1 ELSE 0 END)   AS bulk_orders,
       SUM(CASE WHEN qty >= 3 THEN qty ELSE 0 END) AS bulk_units
FROM   orders
GROUP BY country;
countrytotal_orderssingle_itembulk_ordersbulk_units
IN2113
US2015

Read each SUM(CASE …) as a sentence: “add 1 every time the condition holds, otherwise 0” — that is just counting matching rows. Swap the 1 for a value (like qty) and you get a conditional total instead. The ELSE 0 is not optional: drop it and non-matching rows produce NULL, which SUM silently skips — giving a lower total than you meant.

Practice

Quick check

0/3
Q1A CASE has no ELSE and none of its WHEN conditions match. What does it return?
Q2Why is SUM(CASE WHEN status='paid' THEN amount ELSE 0 END) better than two separate queries?
Q3In a searched CASE with overlapping conditions, which WHEN wins?

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions

Related lessons

Explore further

Skip to content