CASE agrega lógica if/then/else a una consulta SQL: revisa una lista de condiciones y devuelve el resultado de la primera que sea verdadera. Los ejemplos funcionan en PostgreSQL, MySQL, SQLite y SQL Server.
Cómo usar CASE
Escribe pares WHEN condition THEN result entre CASE y END. CASE devuelve el resultado de la primera condición verdadera, o el valor de ELSE si ninguna lo es:
CASE
WHEN condition THEN result
[WHEN condition THEN result ...]
[ELSE result]
END
SELECT
CASE
WHEN 72 >= 90 THEN 'Hot'
WHEN 72 >= 60 THEN 'Mild'
ELSE 'Cold'
END;
-- Output: Mild
Cuando todas las condiciones comparan el mismo valor por igualdad, la forma “simple”, más corta, nombra ese valor una sola vez:
SELECT
CASE 'amber'
WHEN 'green' THEN 'Go'
WHEN 'amber' THEN 'Slow down'
WHEN 'red' THEN 'Stop'
ELSE 'Unknown'
END;
-- Output: Slow down
En una consulta real, las condiciones evalúan columnas y CASE agrega una nueva columna al resultado:
-- Input: orders
-- order_id | amount
-- ---------+--------
-- 1001 | 45.00
-- 1002 | 100.00
-- 1003 | 349.99
-- 1004 | 1250.00
SELECT
order_id,
amount,
CASE
WHEN amount < 100 THEN 'Small'
WHEN amount < 500 THEN 'Medium'
ELSE 'Large'
END AS order_size
FROM orders;
-- Output:
-- order_id | amount | order_size
-- ---------+---------+-----------
-- 1001 | 45.00 | Small
-- 1002 | 100.00 | Medium
-- 1003 | 349.99 | Medium
-- 1004 | 1250.00 | Large
Reglas que debes conocer
-
Gana la primera condición verdadera. Las condiciones se revisan de arriba hacia abajo, así que pon primero la más específica. Arriba,
100.00es Medium porqueamount < 100es falso yamount < 500es verdadero. En el orden equivocado, los montos pequeños nunca llegan a su rama:
SELECT
CASE
WHEN 45 < 500 THEN 'Medium'
WHEN 45 < 100 THEN 'Small' -- can never win
ELSE 'Large'
END;
-- Output: Medium
- Sin ELSE, si nada coincide, el resultado es NULL.
SELECT CASE WHEN 72 >= 90 THEN 'Hot' END;
-- Output: NULL
-
Evalúa NULL con IS NULL.
NULL = NULLno es verdadero, así que la forma simple no puede coincidir con un NULL. Usa la forma con búsqueda:
SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'no match' END;
-- Output: no match
SELECT CASE WHEN NULL IS NULL THEN 'matched' ELSE 'no match' END;
-- Output: matched
- Todos los resultados necesitan un tipo compatible. Mezclar un número y texto en un mismo CASE falla en PostgreSQL y SQL Server, así que convierte el número con cast:
-- Input: products
-- name | stock
-- -------------+------
-- Desk Lamp | 12
-- Office Chair | 0
SELECT name, CASE WHEN stock > 0 THEN stock ELSE 'Sold out' END AS stock
FROM products;
-- PostgreSQL: ERROR: invalid input syntax for type integer: "Sold out"
-- SQL Server: Conversion failed when converting the varchar value 'Sold out' to data type int.
-- (in MySQL, cast with CAST(stock AS CHAR))
SELECT
name,
CASE WHEN stock > 0 THEN CAST(stock AS VARCHAR(10)) ELSE 'Sold out' END AS stock
FROM products;
-- Output:
-- name | stock
-- -------------+---------
-- Desk Lamp | 12
-- Office Chair | Sold out
Sintaxis alternativa
Para una sola condición, también verás una función más corta:
-- MySQL
SELECT IF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
-- SQL Server and SQLite
SELECT IIF(72 >= 60, 'Mild', 'Cold');
-- Output: Mild
Otras dos funciones son atajos de expresiones CASE comunes. COALESCE(nickname, name) equivale a CASE WHEN nickname IS NOT NULL THEN nickname ELSE name END, y NULLIF(a, b) equivale a CASE WHEN a = b THEN NULL ELSE a END. Consulta la guía de COALESCE en SQL para la primera.
MySQL también tiene una sentencia CASE para procedimientos almacenados, que termina con END CASE. Este artículo trata sobre la expresión CASE que usas en las consultas.
¿Cuándo deberías usar CASE?
CASE es una expresión, así que funciona en cualquier lugar donde va un valor: en la lista del SELECT, en ORDER BY y GROUP BY, y dentro de funciones de agregación. También funciona en WHERE, pero ahí suele ser más claro usar AND y OR. La mayoría de los usos entran en uno de estos cinco.
Agrupar números en rangos
Convierte un número en una categoría: niveles de precio, tamaños de pedido, grupos de edad, calificaciones. Escribe las condiciones de un extremo de la escala al otro, para que la primera coincidencia sea la correcta.
Convertir códigos en etiquetas
Las bases de datos guardan códigos cortos como 'A', 'ENG' o 'gold'; la gente quiere palabras. Un CASE simple asigna a cada código una etiqueta, o un valor como un porcentaje de descuento, y ELSE atrapa cualquier código inesperado.
Contar o sumar solo algunas filas
Pon CASE dentro de COUNT o SUM para contar o sumar solo las filas que cumplen una condición. COUNT(CASE WHEN ... THEN 1 END) funciona porque las filas que no coinciden dan NULL, y COUNT las ignora. Una agregación por condición te da varios totales lado a lado, que es como se arma una tabla dinámica en SQL.
Manejar valores faltantes
Revisa columnas en busca de NULL en orden de preferencia y devuelve una etiqueta cuando todas estén vacías. Para un valor de respaldo simple, COALESCE es más corto. CASE es la herramienta indicada cuando cada tipo de hueco necesita un resultado distinto.
Ordenar con un orden personalizado
El orden alfabético y el numérico no sirven para todo: tallas de ropa, prioridades de tickets, una lista con los productos destacados primero. Un CASE en ORDER BY le da a cada valor la posición que quieras.
Ejemplos reales de CASE
Clasificar productos por departamento y precio
Un resultado puede ser otro CASE, así cada departamento tiene sus propios rangos de precio:
-- Input: products
-- product_name | category | price
-- -----------------+-------------+--------
-- Laptop Pro 14 | Electronics | 1499.00
-- Wireless Earbuds | Electronics | 129.00
-- Leather Jacket | Clothing | 349.00
-- Cotton T-Shirt | Clothing | 19.99
-- Coffee Mug | Kitchen | 12.50
SELECT
product_name,
CASE category
WHEN 'Electronics' THEN
CASE
WHEN price > 1000 THEN 'Premium Electronics'
ELSE 'Standard Electronics'
END
WHEN 'Clothing' THEN
CASE
WHEN price > 200 THEN 'Designer Clothing'
ELSE 'Regular Clothing'
END
ELSE 'Other Products'
END AS product_class
FROM products;
-- Output:
-- product_name | product_class
-- -----------------+---------------------
-- Laptop Pro 14 | Premium Electronics
-- Wireless Earbuds | Standard Electronics
-- Leather Jacket | Designer Clothing
-- Cotton T-Shirt | Regular Clothing
-- Coffee Mug | Other Products
Con más de dos niveles, un CASE anidado se vuelve difícil de leer. Una tabla de referencia con un join suele ser más clara.
Aplicar un descuento según el nivel del cliente
Cada código de nivel corresponde a un porcentaje de descuento, y los clientes sin nivel no reciben ninguno:
-- Input: customers
-- id | customer_name | tier
-- ---+---------------+-------
-- 1 | Maya Brooks | gold
-- 2 | Leo Martin | silver
-- 3 | Ava Kim | bronze
-- 4 | Noah Price | NULL
-- Input: orders
-- id | customer_id | order_total
-- ----+-------------+------------
-- 101 | 1 | 200.00
-- 102 | 2 | 150.00
-- 103 | 3 | 80.00
-- 104 | 4 | 60.00
SELECT
customer_name,
order_total,
ROUND(order_total * CASE tier
WHEN 'gold' THEN 0.15
WHEN 'silver' THEN 0.10
WHEN 'bronze' THEN 0.05
ELSE 0
END, 2) AS discount
FROM customers c
JOIN orders o ON c.id = o.customer_id
ORDER BY o.id;
-- Output:
-- customer_name | order_total | discount
-- --------------+-------------+---------
-- Maya Brooks | 200.00 | 30.00
-- Leo Martin | 150.00 | 15.00
-- Ava Kim | 80.00 | 4.00
-- Noah Price | 60.00 | 0.00
Pasar las ventas mensuales a columnas
Un SUM(CASE ...) por mes convierte las filas de ventas en una columna para cada mes:
-- Input: sales
-- product_category | sale_date | amount
-- -----------------+------------+-------
-- Books | 2026-01-12 | 40.00
-- Games | 2026-01-20 | 60.00
-- Books | 2026-02-03 | 25.00
-- Books | 2026-03-15 | 30.00
-- Games | 2026-03-28 | 75.00
SELECT
product_category,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb_sales,
SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar_sales
FROM sales
GROUP BY product_category
ORDER BY product_category;
-- Output:
-- product_category | jan_sales | feb_sales | mar_sales
-- -----------------+-----------+-----------+----------
-- Books | 40.00 | 25.00 | 30.00
-- Games | 60.00 | 0 | 75.00
En SQL Server, usa MONTH(sale_date) = 1 en lugar de EXTRACT; en SQLite, usa strftime('%m', sale_date) = '01'.
Distinguir valores faltantes de valores en blanco
Los datos importados suelen tener tanto NULLs como cadenas vacías. CASE puede etiquetar cada uno para que sepas qué limpiar:
-- Input: users
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 |
-- 3 | NULL
SELECT
id,
CASE
WHEN middle_name IS NULL THEN 'Missing'
WHEN middle_name = '' THEN 'Empty'
ELSE middle_name
END AS middle_name
FROM users;
-- Output:
-- id | middle_name
-- ---+------------
-- 1 | Rose
-- 2 | Empty
-- 3 | Missing
Mostrar primero los productos destacados
Dale a cada categoría una posición de orden y luego ordena por nombre dentro de ella:
-- Input: products
-- product_name | category
-- -------------+------------
-- Wool Scarf | Sale
-- Desk Lamp | Featured
-- Bike Helmet | Clearance
-- Smart Watch | New Arrival
-- Air Fryer | Featured
SELECT product_name, category
FROM products
ORDER BY
CASE category
WHEN 'Featured' THEN 1
WHEN 'New Arrival' THEN 2
WHEN 'Sale' THEN 3
ELSE 4
END,
product_name;
-- Output:
-- product_name | category
-- -------------+------------
-- Air Fryer | Featured
-- Desk Lamp | Featured
-- Smart Watch | New Arrival
-- Wool Scarf | Sale
-- Bike Helmet | Clearance
Más lecturas sobre CASE
En este blog:
- Guía de COALESCE en SQL: la forma corta de usar un valor de respaldo cuando algo es NULL
- Guía de tablas dinámicas en SQL: CASE dentro de SUM y AVG para convertir filas en columnas
- Guía de ORDER BY en SQL: ordenamiento, incluidos órdenes personalizados
- Guía de GROUP BY en SQL: la agrupación en la que se basan los conteos y totales condicionales
- Guía de “distinto de” en SQL: por qué las comparaciones con NULL nunca coinciden
Documentación oficial:
Beekeeper Studio es un cliente de bases de datos gratuito y de código abierto
La mejor herramienta de consultas y edición de SQL que he usado. Tiene todo lo que necesito para administrar mi base de datos. - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studio es rápido, intuitivo y fácil de usar. Es compatible con muchísimas bases de datos y funciona de maravilla en Windows, Mac y Linux.
Lo que dicen los usuarios de Beekeeper Studio
"Beekeeper Studio reemplazó por completo mi antiguo flujo de trabajo con SQL. Es rápido, intuitivo y hace que trabajar con bases de datos vuelva a ser agradable."
"He probado muchas GUIs de bases de datos, pero Beekeeper logra el equilibrio perfecto entre funciones y simplicidad. Simplemente funciona."