CodeGym /Cursos /SQL SELF /Expresiones condicionales: CASE WHEN ... THEN ... ELSE .....

Expresiones condicionales: CASE WHEN ... THEN ... ELSE ... END

SQL SELF
Nivel 10, Lección 0
Disponible

Seguro que ya te has topado con expresiones condicionales en otros lenguajes de programación: if-else, switch-case y cosas así. En SQL tenemos nuestra propia herramienta para trabajar con condiciones: la expresión CASE. Te deja tomar decisiones directamente en las consultas: si la condición se cumple, haces una cosa, si no, otra.

La construcción CASE es especialmente útil cuando tienes que trabajar con datos que pueden tener valores NULL. El sintaxis es súper simple, como una chuleta, mira:

CASE
    WHEN condición1 THEN resultado1
    WHEN condición2 THEN resultado2
    ...
    ELSE resultado_por_defecto
END

¿A que suena lógico? "Si pasa esto, haz esto, si no, haz lo otro". Es fácil de recordar: "WHEN es el si, THEN es lo que haces, ELSE es lo que haces si nada encaja".

Ejemplo: clasificación de productos

Imagina que tenemos una tabla products, con una columna price, y queremos agrupar los productos según su precio.

id name price
1 Magic Wand 120
2 Potion Set 45
3 Crystal Ball 75
4 Enchanted Map NULL
5 Broomstick 99
6 Spell Book 180
SELECT
    name AS product_name,
    price,
    CASE
        WHEN price IS NULL THEN 'Desconocido'
        WHEN price < 50 THEN 'Económico'
        WHEN price BETWEEN 50 AND 100 THEN 'Estándar'
        ELSE 'Premium'
    END AS price_category
FROM products;

¿Qué pasa aquí?

  1. Si el precio price del producto no está puesto (NULL), mostramos la categoría como 'Desconocido'.
  2. Si el precio es menor que 50, el producto es económico 'Económico'.
  3. Si el precio está entre 50 y 100, va a la categoría 'Estándar'.
  4. Todo lo demás son productos premium 'Premium'.

Así queda el resultado:

product_name price price_category
Magic Wand 120 Premium
Potion Set 45 Económico
Crystal Ball 75 Estándar
Enchanted Map NULL Desconocido
Broomstick 99 Estándar
Spell Book 180 Premium

SQL, como un mago, lee las filas de la tabla products, las mira una a una y las clasifica con arte.

Trabajando con NULL en CASE WHEN

Muchas veces hay valores que faltan en los datos (hola, NULL), y hay que ponerles algo. Por ejemplo, tenemos una tabla users con una columna email, y para los usuarios sin correo queremos mostrar 'No especificado'.

user_id name email
1 Alex Lin alex@example.com
2 Maria Chi NULL
3 Anna Song anna@magic.com
4 Otto Art NULL
5 John Smith john@wizard.org
SELECT
    user_id,
    name,
    CASE
        WHEN email IS NULL THEN 'No especificado'
        ELSE email
    END AS email_address
FROM users;
user_id name email_address
1 Alex Lin alex@example.com
2 Maria Chi No especificado
3 Anna Song anna@magic.com
4 Otto Art No especificado
5 John Smith john@wizard.org

SQL aquí actúa como un chamán, rellenando las filas medio vacías. Si falta el email, lo cambia por 'No especificado'. Si hay email, lo deja tal cual.

Expresiones condicionales con números

A veces no solo hay que cambiar valores, sino crear lógica nueva. Por ejemplo, imagina que tenemos una tabla students con columnas score (nota) y name.

name score
Alex Lin 95
Maria Chi 82
Anna Song 48
Otto Art NULL
John Smith 67
Zoe Black 30

Queremos evaluar a los estudiantes como "Excelente", "Aprobado" y "Suspendido", según sus notas.

SELECT
    name AS student_name,
    score,
    CASE
        WHEN score IS NULL THEN 'Sin nota'
        WHEN score >= 90 THEN 'Excelente'
        WHEN score >= 50 THEN 'Aprobado'
        ELSE 'Suspendido'
    END AS performance_category
FROM students;
student_name score performance_category
Alex Lin 95 Excelente
Maria Chi 82 Aprobado
Anna Song 48 Suspendido
Otto Art NULL Sin nota
John Smith 67 Aprobado
Zoe Black 30 Suspendido

SQL reparte a los estudiantes como un profe exigente: 90 puntos o más — solo "Excelente", desde 50 — "Aprobado". Si no llega... ya sabes.

Agrupación y manejo de NULL

Trabajar con grupos de datos es otra área donde CASE WHEN brilla. Imagina que tenemos una tabla orders, y queremos contar el total de pedidos por estado, incluyendo los que tienen NULL como estado.

order_id status
1 Completed
2 Pending
3 NULL
4 Shipped
5 Completed
6 NULL
7 Pending
8 Completed
9 Shipped
10 NULL
SELECT
    CASE
        WHEN status IS NULL THEN 'Sin estado'
        ELSE status
    END AS order_status,
    COUNT(*)
FROM orders
GROUP BY 
    CASE
        WHEN status IS NULL THEN 'Sin estado'
        ELSE status
    END;

Esta consulta maneja los estados vacíos NULL y pone 'Sin estado' en su lugar, además de contar el total de pedidos en cada grupo. Así queda:

order_status count
Completed 3
Pending 2
Shipped 2
Sin estado 3

Casos prácticos: "Trucos" con CASE WHEN

Ejemplo 1: Ordenar teniendo en cuenta NULL

A veces necesitas que los valores NULL salgan primero o al final en una lista ordenada. Esto se usa mucho, por ejemplo, en listas de tareas, donde las tareas prioritarias deben ir arriba y las que no tienen prioridad (NULL) al final.

task_id task_name priority
1 Fix bugs 1
2 Update documentation 3
3 Plan sprint NULL
4 Code review 2
5 Organize meeting NULL
6 Deploy release 1
SELECT
    task_name,
    priority,
    CASE
        WHEN priority IS NULL THEN 1
        ELSE 0
    END AS priority_sort
FROM tasks
ORDER BY priority_sort ASC, priority ASC;

Aquí hemos añadido una columna "virtual" priority_sort, que pone los NULL al final y el resto los ordena de menor a mayor.

task_name priority priority_sort
Deploy release 1 0
Fix bugs 1 0
Code review 2 0
Update documentation 3 0
Plan sprint NULL 1
Organize meeting NULL 1

Ejemplo 2: Cálculos teniendo en cuenta NULL

Ahora imagina que calculamos el precio final de un pedido en la tabla orders, donde la columna discount puede ser NULL si no hay descuento.

order_id total_price discount
101 100 10
102 200 NULL
103 150 15
104 120 NULL
105 80 5

Tenemos que cambiar NULL por 0 para que el cálculo no se rompa.

SELECT 
    order_id,
    total_price,
    discount,
    total_price - 
    CASE
        WHEN discount IS NULL THEN 0
        ELSE discount
    END AS final_price
FROM orders;
order_id total_price discount final_price
101 100 10 90
102 200 NULL 200
103 150 15 135
104 120 NULL 120
105 80 5 75

Este truco mágico con CASE nos asegura que NULL no fastidie los cálculos.

Para orderid = 101: discount = 10. finalprice = 100 - 10 = 90. Para orderid = 102: discount = NULL. CASE devuelve 0. finalprice = 200 - 0 = 200. Para orderid = 103: discount = 15. finalprice = 150 - 15 = 135. Para orderid = 104: discount = NULL. CASE devuelve 0. finalprice = 120 - 0 = 120. Para orderid = 105: discount = 5. finalprice = 80 - 5 = 75.

Ejemplo 3: Mostrar estados de usuario personalizados

En el día a día suele haber que mostrar el estado del usuario (por ejemplo, "Activo" o "Pendiente") o indicar que no hay datos. Por ejemplo, en la tabla users hay una columna last_login con la fecha del último acceso.

user_id name last_login
1 Alex Lin 2024-12-10
2 Maria Chi 2025-04-20
3 Anna Song NULL
4 Otto Art 2025-05-01
5 Liam Park 2025-05-25
SELECT
    user_id,
    name,
    CASE
        WHEN last_login IS NULL THEN 'Nunca ha iniciado sesión'
        WHEN last_login < CURRENT_DATE - INTERVAL '30 days' THEN 'Inactivo'
        ELSE 'Activo'
    END AS user_status
FROM users;

Con esta consulta el sistema de admin cobra vida: los que nunca han entrado son "Nunca ha iniciado sesión", los que llevan mucho sin entrar son "Inactivo". ¡El resto están activos!

user_id name user_status
1 Alex Lin Inactivo
2 Maria Chi Inactivo
3 Anna Song Nunca ha iniciado sesión
4 Otto Art Inactivo
5 Liam Park Activo

Errores comunes y cómo evitarlos

Olvidar ELSE: Si no pones ELSE, SQL simplemente devuelve NULL si ninguna condición se cumple. No siempre es lo que quieres. Así que mejor pon ELSE explícitamente, aunque creas que has cubierto todos los casos.

CASE
    WHEN condition THEN result
    -- ELSE 'Valor por defecto' -- ¡No lo olvides!
END

Condiciones complejas sin paréntesis: Si tienes varias condiciones con AND, OR o NOT, usa siempre paréntesis. Sin ellos tu consulta puede "pensar" mal.

CASE
    WHEN (column1 IS NOT NULL AND column2 > 5) THEN 'Válido'
    ELSE 'Inválido'
END

Trabajando con NULL: Recuerda que NULL nunca es igual (=) a nada. Por ejemplo:

CASE
    WHEN column = NULL THEN '¡Nope!' -- ¡Error!
    WHEN column IS NULL THEN '¡Correcto!' -- Así sí.
END
2
Tarea
SQL SELF, nivel 10, lección 0
Bloqueada
Visualización condicional de datos ausentes
Visualización condicional de datos ausentes
2
Tarea
SQL SELF, nivel 10, lección 0
Bloqueada
Asignación de categorías según valores numéricos
Asignación de categorías según valores numéricos
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION