🎯 Quedan pocos días este mes Apoya SQLTest.online y ayúdanos a mantener la práctica de SQL gratuita para todos. Dona hoy →
Código SQL copiado al portapapeles

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.

SQL CASE WHEN: las condiciones se revisan de arriba abajo, la primera verdadera devuelve su valor, ELSE es el valor por defecto, y CASE sirve para etiquetas y orden personalizado

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 es NULL.

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 en NULL y 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 CASE dentro de funciones de agregación para contar filas por categoría en una sola consulta.

Conclusiones clave:

  • CASE devuelve el resultado de la primera condición WHEN verdadera, o ELSE si ninguna lo es.
  • El CASE de búsqueda revisa cualquier condición; el CASE simple compara una expresión con valores.
  • Sin ELSE, el resultado es NULL.
  • En SELECT, CASE crea categorías y etiquetas legibles.
  • En ORDER BY, define un orden personalizado; en WHERE, 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.

Intenta resolver las siguientes tareas para reforzar lo que aprendiste en esta lección.

  1. Conteo Diario de Vuelos
  2. Ajustar Costo de Alquiler