Chapter 43: PostgreSQL CASE Expression

The CASE expression.

Many beginners see CASE and think:

“This is just like if-else in programming, right? Why bother when I can do it in application code?”

And the honest answer is:

Yes, it is exactly like if-elseif-else — but doing it inside the database is often 10× cleaner, 10× faster, and 10× more maintainable than sending raw data to the application and doing logic there.

CASE is not a statement (it doesn’t change data). It is an expression — it returns a value that you can use anywhere an expression is allowed: in SELECT, WHERE, ORDER BY, GROUP BY, HAVING, UPDATE SET, INSERT VALUES, etc.

PostgreSQL offers two syntax forms of CASE — both are important.

1. Two forms of CASE – understand both

Form 1: Simple CASE (most common – like switch/case)

SQL

Form 2: Searched CASE (more flexible – like if-elseif-else)

SQL
  • The first WHEN that is true wins
  • If none match → ELSE (or NULL if no ELSE)
  • Can be nested (CASE inside CASE) — but don’t overdo it

2. Real, practical examples (using our students & bookstore tables)

Example 1: Simple CASE – classify GPA into letter grades

SQL

Correct (use searched CASE for ranges):

SQL

Result (example):

text

Example 2: CASE in UPDATE (very common real-world use)

SQL

→ Very clean — no multiple UPDATE statements

Example 3: CASE in ORDER BY (super useful for custom sorting)

SQL

→ First show 2025 students, then 2024, then older — within each year sort by GPA descending

Example 4: CASE in WHERE (conditional filtering)

SQL

→ Different stock threshold based on price range

Example 5: CASE with aggregates (inside SELECT)

SQL

→ Very powerful — conditional aggregation without multiple queries

5. Important rules & gotchas (2026 PostgreSQL reality)

Rule / Mistake What happens / Surprise Fix / Best practice
No ELSE clause Returns NULL when no WHEN matches Always add ELSE unless NULL is correct
Multiple WHEN true Only first true WHEN executes Order matters — put most specific first
CASE in WHERE on large table Can prevent index usage Prefer WHERE + CASE in SELECT when possible
Comparing NULL WHEN NULL THEN … never matches Use IS NULL in searched CASE
Nested CASE Allowed — but readability suffers Keep nesting shallow — use multiple CASE or subqueries
Performance Usually very fast — optimizer understands it well Avoid very complex CASE inside hot loops

6. Quick cheat-sheet (keep in your notes)

Goal Typical CASE pattern Alternative (if simpler)
Classify numeric ranges CASE WHEN gpa >= 9 THEN ‘Excellent’ … END
Conditional update UPDATE … SET col = CASE WHEN … THEN … END Multiple UPDATE statements (less clean)
Custom sort order ORDER BY CASE status WHEN ‘urgent’ THEN 1 … END
Conditional count / average SUM(CASE WHEN paid THEN 1 ELSE 0 END) FILTER clause (PostgreSQL 9.4+)
Replace NULL or default value COALESCE(col, CASE … END) COALESCE or NULLIF sometimes simpler

Your mini homework right now

  1. Write CASE query: classify students as ‘High Achiever’ (gpa ≥ 9), ‘Good’ (8–8.99), ‘Average’ (<8)
  2. Add another CASE column: ‘Paid’ or ‘Pending’ based on fees_paid
  3. Write UPDATE using CASE: add 0.5 grace to students enrolled in 2025 with gpa < 8
  4. Use CASE in ORDER BY: show 2025 students first, then 2024, sorted by gpa DESC inside each year

Next class?

Tell me:

  • Want CASE vs FILTER clause (modern aggregate filter) comparison?
  • CASE inside JOIN conditions or WHERE tricky examples?
  • How CASE interacts with NULLs + COALESCE / NULLIF?
  • Or move to WINDOW functions (ROW_NUMBER, RANK, etc.)?

Your teacher is ready — what’s the next topic? 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *