CASE Expressions in PostgreSQL: Conditional Logic in SQL
Learn PostgreSQL's CASE expression — simple and searched forms — for building conditional logic directly inside SELECT, ORDER BY, and WHERE clauses.
CASE Expressions in PostgreSQL
CASE is SQL's equivalent of an if/else chain — it evaluates conditions in order and returns the value tied to the first one that's true.
Searched CASE (Most Common Form)
SELECT name, salary,
CASE
WHEN salary < 40000 THEN 'Junior'
WHEN salary < 80000 THEN 'Mid'
ELSE 'Senior'
END AS salary_band
FROM employees;
Conditions are checked top to bottom — the first match wins, and ELSE catches everything else (it's optional; without it, unmatched rows get NULL).
Simple CASE — Comparing One Value
SELECT name,
CASE department
WHEN 'ENG' THEN 'Engineering'
WHEN 'HR' THEN 'Human Resources'
ELSE department
END AS department_full
FROM employees;
CASE Inside Aggregates — Conditional Counting
A very common pattern: turning a condition into a count without a separate query per condition.
SELECT
COUNT(*) AS total,
COUNT(CASE WHEN gender = 'F' THEN 1 END) AS female_count,
COUNT(CASE WHEN salary > 60000 THEN 1 END) AS high_earners
FROM employees;
COUNT() ignores NULL, so a CASE with no ELSE (returning NULL for non-matches) works perfectly here — only matching rows get counted.
Advertisement728 x 90
CASE in ORDER BY
SELECT name, department
FROM employees
ORDER BY
CASE WHEN department = 'Engineering' THEN 0 ELSE 1 END,
name;
-- Engineering employees first, then everyone else, alphabetically within each group
Common Errors & Troubleshooting
ERROR: CASE types text and integer cannot be matched— everyWHEN ... THENbranch (and theELSE) must return the same (or compatible) data type; mixing a text result in one branch with a number in another causes this error.- Forgetting
ELSEand getting unexpectedNULLs — without anELSE, any row that doesn't match anyWHENcondition returnsNULL, which can silently propagate into further calculations. COUNT(CASE WHEN ... THEN 1 END)returning 0 instead of skipping — this pattern relies onCOUNT()ignoringNULL; if you accidentally writeTHEN 0instead of leaving the implicitNULL(noELSE), every row gets counted, defeating the purpose.
Key Takeaways
CASEevaluates conditions top-to-bottom and returns the first match — order your conditions from most to least specific.COUNT(CASE WHEN condition THEN 1 END)is the standard pattern for conditional counting inside one aggregate query.CASEworks anywhere an expression is valid —SELECT,WHERE,ORDER BY, and even insideGROUP BY.
Advertisement320 x 100