SQL CASE WHEN: lógica condicional en las consultas
Lección 3.5 · Tiempo de lectura: ~7 min · Tareas de práctica ↓
La expresión SQL CASE agrega lógica si-entonces-si no a una consulta: revisa condiciones en orden y devuelve el valor de la primera que es verdadera. En esta lección aprenderás las dos formas de CASE, cómo crear categorías y etiquetas en SELECT, cómo ordenar por una prioridad personalizada y cómo usar CASE en WHERE.
Las funciones de las lecciones anteriores transforman todas las filas de la misma manera. A menudo la regla depende de los datos: un pago menor de $2 es "bajo", mayor de $6 es "alto"; un alquiler sin fecha de devolución está "no devuelto". CASE te permite escribir esas reglas directamente en SQL en lugar de resolverlas en el código de la aplicación.
Sintaxis de CASE
CASE tiene dos formas.
CASE de búsqueda
Cada WHEN contiene su propia condición. Es la forma más flexible y la más común:
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
ELSE default_result
END
CASE simple
Una expresión se compara con una lista de valores:
CASE expression
WHEN value1 THEN result1
WHEN value2 THEN result2
ELSE default_result
END
Cómo se evalúa CASE
- Las condiciones se revisan de arriba abajo.
- Se devuelve el resultado de la primera condición verdadera; las demás no se revisan.
- Si ninguna condición es verdadera, se devuelve el valor de
ELSE. - Si no hay
ELSE, el resultado esNULL.
CASE es una expresión, no una sentencia aparte: devuelve un valor y puede usarse en cualquier lugar donde se admita un valor, en SELECT, WHERE u ORDER BY.
CASE en SELECT: categorías y etiquetas
Niveles de pago
SELECT payment_id,
amount,
CASE
WHEN amount < 2 THEN 'Low'
WHEN amount < 6 THEN 'Medium'
ELSE 'High'
END AS payment_level
FROM payment
LIMIT 10;
Resultado: diez pagos, cada uno con un nivel: menos de $2 "Low", de $2 a menos de $6 "Medium", $6 o más "High".
El orden de las condiciones importa. Un pago de $1 también cumple amount < 6, pero recibe "Low" porque gana la primera rama que coincide. Gracias a eso, la segunda condición no necesita límite inferior.
Un estado legible
SELECT rental_id,
rental_date,
CASE
WHEN return_date IS NULL THEN 'Not returned'
ELSE 'Returned'
END AS rental_status
FROM rental
ORDER BY rental_date DESC
LIMIT 10;
Resultado: los alquileres más recientes con un estado en texto en lugar de una fecha de devolución vacía o completa.
CASE simple para códigos
La forma simple es práctica cuando una columna guarda códigos:
SELECT title,
rating,
CASE rating
WHEN 'G' THEN 'General audiences'
WHEN 'PG' THEN 'Parental guidance'
WHEN 'PG-13' THEN 'Parents strongly cautioned'
WHEN 'R' THEN 'Restricted'
ELSE 'Adults only'
END AS rating_description
FROM film
LIMIT 10;
Resultado: películas con una descripción legible de su clasificación.
CASE en ORDER BY: un orden personalizado
El orden alfabético de los códigos de clasificación (G, NC-17, PG, PG-13, R) no coincide con su significado. CASE convierte cada código en un número de prioridad:
SELECT title, rating
FROM film
ORDER BY CASE rating
WHEN 'G' THEN 1
WHEN 'PG' THEN 2
WHEN 'PG-13' THEN 3
WHEN 'R' THEN 4
ELSE 5
END,
title;
Resultado: películas de la clasificación más suave a la más estricta; dentro de cada clasificación, por título.
La misma técnica pone arriba las filas importantes:
SELECT rental_id, rental_date, return_date
FROM rental
ORDER BY CASE WHEN return_date IS NULL THEN 0 ELSE 1 END,
rental_date DESC
LIMIT 20;
Resultado: primero los alquileres no devueltos, luego el resto; en cada grupo, los más recientes primero.
CASE en WHERE
CASE puede devolver un valor para una condición, por ejemplo un umbral que depende de otra columna:
SELECT payment_id, staff_id, amount
FROM payment
WHERE amount >= CASE
WHEN staff_id = 1 THEN 5
ELSE 3
END
LIMIT 10;
Resultado: pagos de al menos $5 para el empleado 1 y de al menos $3 para los demás.
La mayoría de estos filtros también se pueden escribir con AND y OR: WHERE (staff_id = 1 AND amount >= 5) OR (staff_id <> 1 AND amount >= 3). Elige la versión más fácil de leer: para dos ramas suele ser OR; para muchas ramas, CASE.
Consejos prácticos
- Escribe siempre
ELSE. Sin él, los valores inesperados se convierten enNULLy esas filas pasan fácilmente inadvertidas. - Devuelve un solo tipo de dato. Mezclar texto y números en distintas ramas provoca conversiones implícitas y sorpresas.
- Ordena las condiciones de lo más específico a lo más general. Gana la primera rama verdadera.
- En la lección 4.4 usarás
CASEdentro de funciones de agregación para contar filas por categoría en una sola consulta.
Conclusiones clave:
CASEdevuelve el resultado de la primera condiciónWHENverdadera, oELSEsi ninguna lo es.- El
CASEde búsqueda revisa cualquier condición; elCASEsimple compara una expresión con valores. - Sin
ELSE, el resultado esNULL. - En
SELECT,CASEcrea categorías y etiquetas legibles. - En
ORDER BY, define un orden personalizado; enWHERE, puede hacer que un filtro dependa de otras columnas.
Preguntas frecuentes
¿Cuál es la diferencia entre CASE simple y CASE de búsqueda?
El CASE simple compara una expresión con una lista de valores: CASE rating WHEN 'G' THEN .... El CASE de búsqueda revisa una condición distinta en cada rama: CASE WHEN amount < 2 THEN .... El CASE de búsqueda puede hacer todo lo que hace la forma simple, además de rangos, comprobaciones de NULL y condiciones sobre varias columnas.
¿Qué devuelve CASE si ninguna condición es verdadera y no hay ELSE?
NULL. Para evitar sorpresas, agrega siempre una rama ELSE con un valor por defecto explícito.
¿Existe una función IF en SQL?
CASE es la forma estándar. MySQL y MariaDB también tienen IF(condition, value_if_true, value_if_false), y SQL Server tiene IIF(), pero no son portables.