SQL CASE WHEN Multiple Conditions Guide

Most candidates think CASE WHEN evaluates all conditions and picks the best match. It doesn't. It walks the WHEN list top to bottom and stops at the first TRUE. That one detail is why half the CASE WHEN answers we see in mock interviews bucket rows into the wrong tier. The interviewer isn't checking whether you know the keyword. They're checking whether you know the order of evaluation.

UNKNOWN
What NULL returns
4 sec
Time to spot wrong order
28%
SQL rounds with CASE
1st
TRUE wins, rest skipped
Source: DataDriven analysis of 1,042 verified data engineering interview rounds.
Prepare for the interview
01 / Open invite
02min.

Know CASE WHEN the way the interviewer who asks it knows it.

a CASE WHEN query, the same shape a screen would give you.
The diff against expected. Where ties broke. What you missed.
sandbox
1SELECT user_id,
2 COUNT(*) AS sessions
3FROM events
4WHERE ts >= NOW() - INTERVAL '7 day'
5
Execute your solution0.4s avg.
DoorDashInterview question
Solve a CASE WHEN problem

CASE WHEN Syntax Review

Forget what you think you know. CASE isn't a pattern match, it isn't a scoring function, and it doesn't care about specificity. It reads the WHEN clauses in the order you wrote them, takes the first one that evaluates TRUE, and walks away. Omit ELSE and a row with no match returns NULL, not zero. Most bugs in production dashboards trace back to one of those two facts.
-- General syntax with multiple conditions
CASE
  WHEN condition1 AND condition2 THEN result_a
  WHEN condition3 OR condition4  THEN result_b
  WHEN condition5               THEN result_c
  ELSE default_result
END

-- Searched CASE (most flexible)
SELECT
  CASE
    WHEN age_bucket = '65+' AND account_status = 'inactive' THEN 'Senior Discount'
    WHEN age_bucket = '18-24' OR account_status = 'student' THEN 'Student Rate'
    ELSE 'Standard Rate'
  END AS pricing_tier
FROM users;

-- Simple CASE (equality only, no AND/OR)
SELECT
  CASE account_status
    WHEN 'active' THEN 'Active'
    WHEN 'inactive' THEN 'Inactive'
    WHEN 'pending' THEN 'Pending'
    ELSE 'Unknown'
  END AS status_label
FROM users;
Simple vs Searched: Simple CASE (CASE column WHEN value) only supports equality checks. Searched CASE (CASE WHEN condition) supports AND, OR, inequalities, IS NULL, and any boolean expression. Always use searched CASE for multiple conditions.

Nth Highest Salary Per Department

> For each department, find the employee with the third-highest salary. If a department has fewer than 3 employees, exclude it. Return department, employee name, and their salary.

5 CASE WHEN Patterns

From sequential WHEN clauses to AND/OR conditions, nested CASE expressions, and conditional aggregation inside GROUP BY queries.

Multiple WHEN Clauses (Sequential Evaluation)

CASE evaluates WHEN clauses from top to bottom and returns the result for the first condition that is TRUE. Once a match is found, remaining clauses are skipped. This means the order of your WHEN clauses matters. Put the most specific or most restrictive conditions first. The ELSE clause handles any rows that do not match any WHEN condition.

-- Categorize transactions by size
SELECT
  transaction_id,
  total_amount,
  CASE
    WHEN total_amount >= 10000 THEN 'Enterprise'
    WHEN total_amount >= 1000  THEN 'Mid-Market'
    WHEN total_amount >= 100   THEN 'Small Business'
    ELSE 'Micro'
  END AS order_tier
FROM transactions;

-- Order matters: a $15,000 transaction matches the first clause
-- and is labeled 'Enterprise'. The second clause is never
-- checked for that row, even though $15,000 >= 1000 is true.

CASE WHEN with AND (Multiple Conditions per Clause)

AND combines multiple conditions within a single WHEN clause. All conditions must be TRUE for the clause to match. This pattern handles business rules that depend on two or more factors simultaneously: an order is 'Priority' only if the amount is high AND the customer is VIP. Both conditions must hold.

-- Flag high-value orders from premium accounts for expedited shipping
SELECT
  t.transaction_id,
  u.account_status,
  t.total_amount,
  CASE
    WHEN u.account_status = 'premium' AND t.total_amount >= 5000
      THEN 'Priority Ship'
    WHEN u.account_status = 'premium' AND t.total_amount < 5000
      THEN 'Standard Ship'
    WHEN t.total_amount >= 5000
      THEN 'Expedited Ship'
    ELSE 'Standard Ship'
  END AS shipping_tier
FROM transactions t
JOIN users u ON u.user_id = t.user_id;

-- Row with premium + $8,000: matches first clause
-- Row with premium + $200: matches second clause
-- Row with regular + $6,000: matches third clause
-- Row with regular + $50: falls to ELSE

CASE WHEN with OR (Alternative Conditions)

OR allows a single WHEN clause to match any of several conditions. The clause fires if at least one condition is TRUE. Use OR when multiple distinct scenarios should produce the same result. This reduces duplication compared to writing separate WHEN clauses that all return the same value.

-- Identify accounts needing review
SELECT
  user_id,
  account_status,
  signup_date,
  CASE
    WHEN account_status = 'closed' OR account_status = 'suspended'
      THEN 'Immediate Review'
    WHEN account_status = 'inactive' OR signup_date < '2020-01-01'
      THEN 'Routine Review'
    ELSE 'No Action'
  END AS review_action
FROM users;

-- Closed OR suspended status: same action needed
-- Inactive OR signed up before 2020: same review tier

Nested CASE Expressions

A CASE expression can appear inside another CASE expression. The outer CASE handles the first decision. The inner CASE refines the result based on additional criteria. This pattern is useful when the logic has a natural hierarchy: first determine the category, then within that category determine the subcategory. Keep nesting to two levels maximum; deeper nesting becomes unreadable.

-- Tiered pricing based on account type and volume
SELECT
  oi.user_id,
  u.account_status,
  oi.quantity,
  oi.unit_price,
  CASE
    WHEN u.account_status = 'premium' THEN
      CASE
        WHEN oi.quantity >= 1000 THEN oi.unit_price * 0.70
        WHEN oi.quantity >= 100  THEN oi.unit_price * 0.85
        ELSE oi.unit_price * 0.90
      END
    WHEN u.account_status = 'active' THEN
      CASE
        WHEN oi.quantity >= 500 THEN oi.unit_price * 0.90
        ELSE oi.unit_price * 0.95
      END
    ELSE oi.unit_price
  END AS final_price
FROM order_items oi
JOIN users u ON u.user_id = oi.user_id;

CASE WHEN Inside Aggregate Functions

Placing CASE WHEN inside COUNT, SUM, or AVG creates conditional aggregation. This computes different metrics from the same rows in a single pass. It replaces multiple filtered subqueries and is one of the most powerful reporting patterns in SQL. Combined with GROUP BY, it produces cross-tabulation reports.

-- Single query: multiple conditional metrics
SELECT
  department,
  COUNT(*) AS total_employees,
  COUNT(CASE WHEN salary >= 100000 THEN 1 END) AS high_earners,
  SUM(CASE WHEN manager_id IS NOT NULL THEN salary ELSE 0 END) AS reports_payroll,
  AVG(CASE
    WHEN hire_date < '2020-01-01' AND salary >= 90000
    THEN salary
  END) AS avg_salary_senior_performers
FROM employees
GROUP BY department;

-- COUNT(CASE...) counts only rows where the condition is true
-- NULL results from unmatched CASE are ignored by COUNT
-- SUM uses ELSE 0 to avoid NULL in the sum

Common CASE WHEN Pitfalls

These mistakes are silent. The query runs, the results look plausible, and the bug only surfaces when someone checks the numbers.

Pitfall 1: Wrong WHEN clause order with overlapping conditions

  • CASE short-circuits on the first match. If a broad condition appears before a specific one, the specific clause never fires.
  • Fix: Put the most specific (restrictive) conditions first.

Pitfall 2: Missing NULL handling

  • WHEN column = 'value' does not match rows where column is NULL. NULL = anything is UNKNOWN, not FALSE. These rows fall through all WHEN clauses and hit ELSE (or become NULL if there is no ELSE).
  • Fix: Add WHEN column IS NULL THEN 'default' as an explicit clause, or use COALESCE(column, 'fallback') before the comparison.

Pitfall 3: No ELSE clause when NULL is not acceptable

  • Without ELSE, CASE returns NULL when no WHEN matches. If the result feeds into arithmetic (NULL + 5 = NULL) or a WHERE filter (NULL is not TRUE), downstream logic breaks silently.
  • Fix: Always include ELSE unless you deliberately want NULL for unmatched rows. For conditional aggregation (COUNT(CASE...)), omitting ELSE is intentional because COUNT ignores NULLs.

3 CASE WHEN Interview Questions

Q1: Write a CASE expression that categorizes customers into risk tiers based on multiple factors: account age, balance, and transaction frequency.

What they test: Ability to combine multiple conditions with AND/OR inside WHEN clauses. The interviewer wants to see you handle a multi-factor decision tree cleanly. They also check whether you order your WHEN clauses correctly (most restrictive first) and include an ELSE for the default case. Approach: Define the tiers clearly before writing SQL. High risk: balance < 0 OR (account_age < 30 AND transaction_count = 0). Medium risk: balance < 500 AND transaction_count < 5. Low risk: everything else. Write the CASE with the most critical conditions first. Explain that order matters because CASE short-circuits on the first match. Add ELSE 'Low Risk' as the catch-all.

Q2: Rewrite a query that uses multiple LEFT JOINs to count different order statuses into a single query using CASE WHEN inside COUNT.

What they test: Whether you understand conditional aggregation as an alternative to multiple joins or subqueries. This tests both CASE WHEN proficiency and query optimization awareness. Conditional aggregation scans the table once instead of joining it multiple times. Approach: Show the before (three LEFT JOINs to subqueries counting pending, shipped, and cancelled orders) and the after (single GROUP BY with COUNT(CASE WHEN status = 'pending' THEN 1 END) for each status). Explain that the CASE returns NULL for non-matching rows and COUNT ignores NULLs, so each COUNT only tallies the matching status. Mention the performance benefit: one table scan vs three.

Q3: A CASE expression returns unexpected NULL values for some rows. All WHEN conditions look correct. What is the problem?

What they test: Understanding of CASE default behavior and NULL comparison pitfalls. When no WHEN clause matches and there is no ELSE, CASE returns NULL. Also, WHEN column = value does not match when column is NULL because NULL = anything is UNKNOWN, not TRUE. Approach: Two common causes. First: missing ELSE clause. If no WHEN matches, CASE returns NULL. Always add an ELSE unless you intentionally want NULL. Second: NULL input values. WHEN status = 'active' does not match rows where status IS NULL. To handle NULLs, add a specific clause: WHEN status IS NULL THEN 'Unknown'. Or use COALESCE on the input: WHEN COALESCE(status, 'unknown') = 'active'.

Frequently asked questions

How do I use multiple conditions in a SQL CASE WHEN?+
Use AND to require all conditions in a single WHEN clause: WHEN amount > 1000 AND status = 'active' THEN 'High Priority'. Use OR to match any of several conditions: WHEN status = 'expired' OR status = 'suspended' THEN 'Inactive'. You can combine AND and OR with parentheses: WHEN (status = 'active' AND balance > 0) OR vip_flag = true THEN 'Valid'.
What is the difference between multiple WHEN clauses and AND conditions?+
Multiple WHEN clauses evaluate independently in order, and each can return a different result. AND within a single WHEN clause requires all conditions to be true for that single result. Use multiple WHENs when different condition combinations map to different outcomes. Use AND when several factors must all be true for one specific outcome.
Can I nest CASE expressions inside each other?+
Yes. Place a complete CASE...END expression where you would normally put a result value. The outer CASE handles the first decision, and the inner CASE refines it. Limit nesting to two levels for readability. If your logic requires three or more levels, consider using a CTE with intermediate columns or a lookup table join instead.
02 / Why practice

The interviewer isn't testing syntax

  1. 01

    Active recall beats re-reading by 50%

    Cognitive-science meta-reviews (Dunlosky et al., 2013) rank practice testing as a top-tier study technique, while re-reading and highlighting rank near the bottom

  2. 02

    76% of hiring managers reject on the coding task, not the resume

    From HackerRank's 2024 Developer Skills Report. Candidates who look strong on paper still fail the live screen if they haven't done timed, executable practice

  3. 03

    Five problem shapes cover 80% of data engineer loops

    Dedup, sessionization, top-N-per-group, slowly-changing dimensions, partition tricks. Writing the shapes by hand turns the unfamiliar into pattern recognition

More reading