6.1 CASE y el tratamiento de NULL¶
CASE: decidir dentro de una consulta¶
CASE es el «si... entonces... si no...» de SQL: devuelve un valor u otro según una condición.
CASE
WHEN condición1 THEN valor1
WHEN condición2 THEN valor2
ELSE valor_por_defecto
END
Las condiciones se evalúan de arriba abajo y gana la primera que se cumple. Por ejemplo, convertir las notas en calificaciones con letra:
SELECT id_alumno, id_asignatura, nota,
CASE
WHEN nota >= 9 THEN 'Sobresaliente'
WHEN nota >= 7 THEN 'Notable'
WHEN nota >= 5 THEN 'Aprobado'
ELSE 'Suspenso'
END AS calificacion
FROM notas
WHERE convocatoria = 1
ORDER BY nota DESC;
Resultado:
| id_alumno | id_asignatura | nota | calificacion |
|---|---|---|---|
| 6 | 3 | 10.0 | Sobresaliente |
| 5 | 4 | 9.5 | Sobresaliente |
| 6 | 1 | 9.5 | Sobresaliente |
| 12 | 5 | 9.5 | Sobresaliente |
| 1 | 3 | 9.0 | Sobresaliente |
| 8 | 2 | 9.0 | Sobresaliente |
| … | … | … | … |
46 filas (se muestran 6)
(Es el mismo razonamiento que un if / else if / else de un lenguaje de programación: el orden importa.)
Contar con condiciones¶
La combinación más útil: un CASE dentro de un agregado para contar o sumar solo lo que cumple algo, y así obtener varias cifras en una sola consulta. Aprobados y suspensos de cada asignatura:
SELECT s.nombre AS asignatura,
SUM(CASE WHEN n.nota >= 5 THEN 1 ELSE 0 END) AS aprobados,
SUM(CASE WHEN n.nota < 5 THEN 1 ELSE 0 END) AS suspensos
FROM notas n
JOIN asignaturas s ON s.id = n.id_asignatura
WHERE n.convocatoria = 1
GROUP BY s.id, s.nombre
ORDER BY s.nombre;
Resultado:
| asignatura | aprobados | suspensos |
|---|---|---|
| Bases de Datos | 8 | 5 |
| Entornos de Desarrollo | 7 | 1 |
| Inglés Técnico | 3 | 1 |
| Lenguajes de Marcas | 6 | 2 |
| Programación | 7 | 2 |
| Sistemas Informáticos | 4 | 0 |
6 filas
Cada nota aporta un 1 a una de las dos columnas y un 0 a la otra; al sumar por asignatura salen los totales.
Manejar los NULL¶
Un NULL en un cálculo contagia: 5 + NULL es NULL, y concatenar un texto con NULL da NULL. Tres funciones lo controlan:
| Función | Qué hace | Ejemplo |
|---|---|---|
COALESCE(a, b, ...) |
Devuelve el primer valor que no sea NULL |
COALESCE(profesor, 'Sin asignar') |
IFNULL(a, b) |
Lo mismo con dos valores (en MySQL y SQLite) | IFNULL(id_grupo, 0) |
NULLIF(a, b) |
Devuelve NULL si a es igual a b (útil para evitar dividir entre 0) |
x / NULLIF(y, 0) |
Mostrar «Sin asignar» donde no hay profesor:
SELECT s.nombre AS asignatura, COALESCE(p.nombre, 'Sin asignar') AS profesor
FROM asignaturas s
LEFT JOIN profesores p ON p.id = s.id_profesor;
Resultado:
| asignatura | profesor |
|---|---|
| Programación | Marta Ruiz |
| Bases de Datos | Pedro Salas |
| Entornos de Desarrollo | Lucía Ferrer |
| Lenguajes de Marcas | Lucía Ferrer |
| Sistemas Informáticos | Hugo Navas |
| Inglés Técnico | Sin asignar |
6 filas
Y evitar la división por cero (en SQLite dividir entre 0 da NULL; en otros motores da un error, y NULLIF evita el error):
SELECT 10 / NULLIF(0, 0) AS resultado;
Resultado:
| resultado |
|---|
| NULL |
1 fila
Una condición como valor¶
Una comparación puede usarse como un valor: en SQLite devuelve 1 (verdadero) o 0 (falso), y por eso se puede sumar para contar:
SELECT COUNT(*) AS notas, SUM(nota >= 5) AS aprobadas FROM notas WHERE convocatoria = 1;
Resultado:
| notas | aprobadas |
|---|---|
| 46 | 35 |
1 fila
Según el motor
La suma de condiciones funciona en SQLite y MySQL. En PostgreSQL y Oracle las condiciones no son números: hay que usar el CASE de arriba (por eso es la forma más portable). Algunos motores también tienen IIF(condición, a, b) (SQLite, SQL Server) o IF(condición, a, b) (MySQL).
Errores frecuentes¶
| Error | Cómo evitarlo |
|---|---|
CASE sin ELSE |
Si ninguna condición se cumple, devuelve NULL: añade el ELSE |
| Condiciones en mal orden | Gana la primera que se cumple: de la más restrictiva a la más general |
WHERE col = NULL |
IS NULL |
Un cálculo con un NULL que «borra» el resultado |
COALESCE para dar un valor por defecto |
| Dividir entre una columna que puede valer 0 | NULLIF(columna, 0) |
Para practicar¶
Los ejercicios S6.1 a S6.3 de S6 · Ejercicios practican CASE y COALESCE.