5.4 Conditional Expressions: CASE and DECODE
Key Takeaways
- Oracle SQL provides conditional IF-THEN-ELSE branching through two constructs: the ANSI SQL standard CASE expression and the Oracle-proprietary DECODE function.
- Simple CASE tests a single selector against discrete values using exact equality, whereas Searched CASE evaluates independent boolean conditions (including ranges, IS NULL, and compound logic).
- A critical distinction is that DECODE treats two NULL values as equivalent, whereas Simple CASE cannot match NULL with 'WHEN NULL' (Searched CASE with 'WHEN expr IS NULL' must be used).
- In a CASE expression, all return branches (THEN and ELSE) must share compatible datatypes coerced to the first THEN branch; omitting ELSE defaults to returning NULL if no conditions match.
- In DECODE, the return datatype is strictly determined by the first result expression; DECODE is limited to equality comparisons, whereas Searched CASE supports full relational predicates.
5.4 Conditional Expressions: CASE and DECODE
SQL is a declarative language designed to express what data to retrieve rather than how to procedurally fetch it. However, real-world reporting and data manipulation frequently require conditional logic—the SQL equivalent of IF-THEN-ELSE branching statements found in procedural languages.
Oracle SQL provides two primary mechanisms for implementing conditional expressions:
- The
CASEExpression: An ANSI SQL compliant, highly flexible expression supporting both equality matching and complex boolean range evaluations. - The
DECODEFunction: An Oracle-proprietary built-in function providing compact equality-based mapping with unique NULL-handling semantics.
The CASE Expression
The CASE expression complies with ANSI SQL standards and can be utilized anywhere a standard scalar expression is valid (e.g., SELECT lists, WHERE clauses, ORDER BY clauses, GROUP BY expressions, and HAVING filters).
Oracle supports two distinct forms of the CASE expression:
+----------------------------+
| CASE EXPRESSION |
+----------------------------+
|
+-----------------------------+-----------------------------+
| |
v v
+----------------------------+ +----------------------------+
| SIMPLE CASE | | SEARCHED CASE |
| Evaluates exact equality | | Evaluates independent |
| against a single selector. | | boolean conditions. |
+----------------------------+ +----------------------------+
1. Simple CASE Expression
A Simple CASE expression evaluates a single test expression (the selector) against a sequence of discrete comparison values using strict equality (selector = comparison_expr):
CASE selector
WHEN value_1 THEN result_1
WHEN value_2 THEN result_2
[WHEN value_N THEN result_N]
[ELSE default_result]
END
Simple CASE Example:
SELECT employee_id, last_name, job_id,
CASE job_id
WHEN 'IT_PROG' THEN 'Information Technology'
WHEN 'SA_REP' THEN 'Sales Representative'
WHEN 'ST_CLERK' THEN 'Stock Clerk'
ELSE 'Other Role'
END AS job_category
FROM employees;
Critical Exam Rule: Simple
CASECANNOT evaluate NULL values usingWHEN NULL. Because SimpleCASEtests equality (selector = NULL), the comparison yieldsUNKNOWN(falsy) for every row. To test forNULL, you must use a Searched CASE withIS NULL.
2. Searched CASE Expression
A Searched CASE expression does not use a selector; instead, each WHEN clause contains an independent boolean search condition. Oracle evaluates these conditions sequentially from top to bottom and returns the THEN result of the first condition that evaluates to TRUE:
CASE
WHEN boolean_condition_1 THEN result_1
WHEN boolean_condition_2 THEN result_2
[WHEN boolean_condition_N THEN result_N]
[ELSE default_result]
END
Searched CASE Example (Ranges, Compound Logic & NULL Testing):
SELECT employee_id, last_name, salary, commission_pct,
CASE
WHEN commission_pct IS NOT NULL THEN 'Commission Earner'
WHEN salary >= 15000 THEN 'Executive Level'
WHEN salary BETWEEN 8000 AND 14999 THEN 'Senior Staff'
WHEN salary < 8000 AND department_id = 50 THEN 'Operations Regular'
ELSE 'Standard Base'
END AS compensation_tier
FROM employees;
Structural Rules for CASE Expressions:
- The Mandatory
ENDKeyword: EveryCASEexpression must terminate with theENDkeyword. OmittingENDresults in anORA-00905: missing keywordcompilation error. - Optional
ELSEClause: TheELSEclause is optional. IfELSEis omitted and noWHENcondition evaluates toTRUE, theCASEexpression returnsNULL. - Datatype Consistency: All return expressions (
result_1,result_2, ...,default_result) must share compatible datatypes. Oracle coerces subsequent return values to the datatype of the firstTHENreturn expression (result_1). - Short-Circuit Evaluation: Oracle stops evaluating subsequent
WHENbranches as soon as it encounters the first condition that evaluates toTRUE.
The DECODE Function
The DECODE function is an Oracle-proprietary SQL function that emulates IF-THEN-ELSE logic specifically for equality comparisons.
Syntax:
DECODE(expr, search_1, result_1
[, search_2, result_2, ...]
[, default_result])
SELECT employee_id, last_name, department_id,
DECODE(department_id, 10, 'Administration',
20, 'Marketing',
30, 'Purchasing',
40, 'Human Resources',
'Other Department') AS dept_name
FROM employees;
Special Semantic Rules for DECODE:
- Pairwise Arguments:
DECODErequires at least 3 arguments (expr,search_1,result_1). If arguments are not properly paired, Oracle raisesORA-00938: not enough arguments for function. - Optional Default: The final
default_resultargument is optional. If omitted andexprdoes not match any search value,DECODEreturnsNULL. - NULL Equality Semantics: In standard SQL and
CASEexpressions,NULL = NULLevaluates toUNKNOWN. InDECODE, Oracle considers twoNULLvalues to be equal!-- DECODE matches NULL successfully: SELECT last_name, DECODE(commission_pct, NULL, 'No Commission', 'Commissioned') AS comm_status FROM employees; - Datatype Coercion in DECODE: The return datatype of
DECODEis determined by the datatype ofresult_1:- If
result_1is character, subsequent results are converted toVARCHAR2. - If
result_1is numeric, subsequent results are converted toNUMBER. - If
result_1isNULL, the return datatype isVARCHAR2.
- If
Comparative Matrix: CASE vs. DECODE
| Feature | CASE Expression | DECODE Function |
|---|---|---|
| Standard Compliance | ANSI SQL Standard (Portable across RDBMS) | Oracle Proprietary |
| Construct Category | Expression (Grammar construct) | Built-in Function |
| Evaluation Types | Equality (Simple) OR Complex Boolean/Ranges (Searched) | Equality comparisons only |
| NULL Equality | WHEN NULL fails; requires WHEN expr IS NULL | Equates NULL with NULL automatically |
| Logical Operators | Supports AND, OR, NOT, LIKE, IN, BETWEEN | No logical operators supported |
| Datatype Rules | Coerced to datatype of first THEN branch | Coerced to datatype of result_1 |
| Argument Limit | Unlimited practical depth | Up to 255 components |
| PL/SQL Usage | Supported as both expression and statement | Supported only in SQL queries (not procedural PL/SQL engine) |
Side-by-Side SQL Rewrites: DECODE to Searched CASE
Understanding how to translate DECODE expressions into ANSI CASE expressions (and vice versa) is a heavily tested skill on the 1Z0-071 examination.
Rewrite 1: NULL Matching
-- DECODE with NULL matching:
SELECT DECODE(manager_id, NULL, 'Top Executive', 'Subordinate') FROM employees;
-- Equivalent Searched CASE:
SELECT CASE
WHEN manager_id IS NULL THEN 'Top Executive'
ELSE 'Subordinate'
END
FROM employees;
Rewrite 2: Simulating Range Evaluations with SIGN()
Before CASE was introduced in Oracle 8i, developers used the SIGN() function inside DECODE to evaluate numeric inequalities:
-- Legacy DECODE simulating ranges using SIGN(salary - 10000):
-- SIGN() returns 1 if positive, -1 if negative, 0 if equal.
SELECT DECODE(SIGN(salary - 10000), 1, 'High Earner',
0, 'Exact Target',
'Standard Earner') AS tier
FROM employees;
-- Clean, modern Searched CASE rewrite:
SELECT CASE
WHEN salary > 10000 THEN 'High Earner'
WHEN salary = 10000 THEN 'Exact Target'
ELSE 'Standard Earner'
END AS tier
FROM employees;
Advanced Pattern: Conditional Aggregation
CASE and DECODE can be nested inside aggregate functions to pivot or calculate conditional metrics in a single pass over a table:
-- Calculating department headcounts by compensation level in a single query:
SELECT department_id,
COUNT(*) AS total_employees,
COUNT(CASE WHEN salary >= 10000 THEN 1 END) AS high_earners,
COUNT(CASE WHEN salary < 10000 THEN 1 END) AS standard_earners,
SUM(DECODE(job_id, 'IT_PROG', salary, 0)) AS it_payroll
FROM employees
GROUP BY department_id
ORDER BY department_id;
Exam Trap: In conditional
COUNT(), remember thatCOUNT(expr)only tallies non-null values. By omittingELSEinCASE WHEN salary >= 10000 THEN 1 END, rows where salary is below 10,000 evaluate toNULL, whichCOUNTignores.
A developer writes the following Simple CASE query to identify employees without a manager: SELECT employee_id, last_name, CASE manager_id WHEN NULL THEN 'No Manager' ELSE 'Has Manager' END AS mgr_status FROM employees; What is the result for an employee whose MANAGER_ID is NULL?
Which of the following statements is TRUE regarding the NULL-handling behavior of DECODE compared to CASE?
Examine the following SQL statement: SELECT department_id, DECODE(department_id, 10, 'Ten', 20, 200, 'Other') AS dept_code FROM employees WHERE employee_id = 100; If employee 100 belongs to department 20, what is the datatype and value returned by the DECODE expression for DEPT_CODE?