CodeGym /Courses /SQL SELF /Conditional expressions: CASE <expression> W...

Conditional expressions: CASE <expression> WHEN ... THEN ... ELSE ... END

SQL SELF
Level 10 , Lesson 1
Available

If you already know about CASE, it’s a way to embed logic right into your query. But not everyone knows that CASE comes in two flavors. If CASE WHEN ... is like an if-else check, then simple CASE is like switch-case from other languages: it compares one expression to several values and runs the matching block.

It looks more compact and intuitive when you’re comparing one field to fixed values.

Simple CASE syntax

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

It’s super simple:

  • expression — this is the expression or field you’re comparing to value1, value2, etc.
  • THEN tells what to return if there’s a match.
  • ELSE — what to return if nothing matched (you can skip it, but it’s better not to).

Example: Student grades

Imagine a students table with a grade column, holding an integer from 2 to 5. We want to show a text version of the grades.

SELECT
    name,
    grade,
    CASE grade
        WHEN 5 THEN 'Excellent'
        WHEN 4 THEN 'Good'
        WHEN 3 THEN 'Satisfactory'
        WHEN 2 THEN 'Unsatisfactory'
        ELSE 'Unknown'
    END AS grade_in_words
FROM students;

Here, CASE compares the grade field to the fixed values 2, 3, 4, 5.

Example: Product categories by code

In the products table there’s a category_code field with short tags: 'el', 'frn', 'bks', etc. We want to show a readable category name.

SELECT
    product_name,
    category_code,
    CASE category_code
        WHEN 'el' THEN 'Electronics'
        WHEN 'frn' THEN 'Furniture'
        WHEN 'bks' THEN 'Books'
        ELSE 'Other'
    END AS category_name
FROM products;

This trick is especially handy when you want to show "human" text instead of a code.

Example: Month names

Sometimes you want to show month names as text by their number:

SELECT
    EXTRACT(MONTH FROM order_date) AS month_number,
    CASE EXTRACT(MONTH FROM order_date)
        WHEN 1 THEN 'January'
        WHEN 2 THEN 'February'
        WHEN 3 THEN 'March'
        WHEN 4 THEN 'April'
        WHEN 5 THEN 'May'
        WHEN 6 THEN 'June'
        WHEN 7 THEN 'July'
        WHEN 8 THEN 'August'
        WHEN 9 THEN 'September'
        WHEN 10 THEN 'October'
        WHEN 11 THEN 'November'
        WHEN 12 THEN 'December'
        ELSE 'Unknown'
    END AS month_name
FROM orders;

Here, simple CASE makes it clear what would otherwise just look like numbers from 1 to 12.

Working with NULL in simple CASE

It’s important to know that if you compare a value to NULL, the result will be NULL, because NULL = NULL is not true, it’s unknown.

Example with NULL:

SELECT
    user_id,
    status,
    CASE status
        WHEN 'active' THEN 'Active'
        WHEN 'blocked' THEN 'Blocked'
        WHEN NULL THEN 'No status'  -- won’t work!
        ELSE 'Unknown'
    END AS user_state
FROM users;

Instead of WHEN NULL you should use ELSE, or just use a searched CASE (which we covered in the last lecture):

CASE
    WHEN status IS NULL THEN 'No status'
    ...

Comparison with searched CASE

Feature Simple CASE Searched CASE
Compare to specific values ✅ Handy ❌ Not for this
Flexible conditions (>, IS NULL) ❌ Can’t do it ✅ You can
Programming analogy switch-case if-else

Practical cases

Example: Visualizing request status

request_id status
101 new
102 in_progress
103 done
104 cancelled
105 NULL
SELECT
    request_id,
    CASE status
        WHEN 'new' THEN '🟡 New'
        WHEN 'in_progress' THEN '🔵 In progress'
        WHEN 'done' THEN '🟢 Completed'
        ELSE '⚪ Unknown'
    END AS status_label
FROM requests;
request_id status_label
101 🟡 New
102 🔵 In progress
103 🟢 Completed
104 ⚪ Unknown
105 ⚪ Unknown

Here CASE acts like a translator: it turns technical statuses into clear (and even cute) labels. And if the status is unknown or NULL — the user gets ⚪ “Unknown”.

Example: Grouping by category for a report

employee_id name department
1 Alex Lin HR
2 Maria Chi IT
3 Anna Song IT
4 Otto Art FIN
5 Jane Doe HR
6 Max Gray SALES
7 Zoe Black IT
8 Tom Brown FIN
9 Liam Park NULL
10 Eva Gold HR
SELECT
    CASE department
        WHEN 'HR' THEN 'HR'
        WHEN 'IT' THEN 'Tech'
        WHEN 'FIN' THEN 'Finance'
        ELSE 'Other'
    END AS dept_name,
    COUNT(*) AS staff_count
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN 'HR'
        WHEN 'IT' THEN 'Tech'
        WHEN 'FIN' THEN 'Finance'
        ELSE 'Other'
    END;

Result:

dept_name staff_count
HR 3
Tech 3
Finance 2
Other 2

What’s happening here:

  • Employees from the HR department go into the HR category.
  • IT — that’s Tech.
  • FIN — that’s Finance.
  • Everything else, including SALES and NULL, goes into Other. This approach is great for making friendly and clear reports.

Common mistakes

  • Forgot ELSE → you get NULL if nothing matched.
  • Comparing to NULL → doesn’t work, use IS NULL and searched CASE.
  • Comparing incompatible types → for example, CASE grade WHEN '5' if grade is a number type.

Simple CASE is your tool when you need to compare one value to a set of possible ones. It’s compact, readable, and especially useful for text classification, visualization, code conversion, and easy grouping.

But if you need to check ranges, NULL, or more complex conditions — go for searched CASE. SQL loves clarity. And CASE is your tool to give that clarity some shape.

2
Task
SQL SELF, level 10, lesson 1
Locked
Assigning Text Descriptions to Grades
Assigning Text Descriptions to Grades
2
Task
SQL SELF, level 10, lesson 1
Locked
Comparing Product Categories
Comparing Product Categories
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION