CASE: expresar decisiones dentro de una consulta
Una consulta no siempre debe devolver el valor exactamente como está almacenado. A veces necesitamos clasificar una existencia, traducir un estado o calcular un valor distinto según una condición.
CASE permite evaluar esas condiciones y producir un resultado. Una expresión es una combinación de valores y operaciones que devuelve un valor. CASE no controla el flujo general del procedimiento —qué instrucciones se ejecutan—: construye una expresión que puede utilizarse dentro de SELECT, ORDER BY, UPDATE y otras instrucciones.
La idea
CASE revisa sus condiciones en el orden escrito y devuelve el resultado de la primera que se cumple. Si ninguna coincide, utiliza ELSE. Cuando omitimos ELSE, el resultado es NULL, la marca que representa un valor ausente o desconocido.
Esto significa que el orden importa. Una condición amplia colocada primero puede impedir que se evalúe otra más específica.
Sintaxis
CASE
WHEN Condicion1 THEN Resultado1
WHEN Condicion2 THEN Resultado2
ELSE ResultadoAlternativo
END
También existe la forma simple, útil cuando comparamos una sola expresión con varios valores:
CASE Expresion
WHEN Valor1 THEN Resultado1
WHEN Valor2 THEN Resultado2
ELSE ResultadoAlternativo
END
Ejemplo: clasificar la existencia
Queremos mostrar una descripción más útil que la cantidad aislada:
SELECT
p.IdProducto,
p.Nombre,
p.Existencia,
CASE
WHEN p.Existencia = 0 THEN 'Sin existencia'
WHEN p.Existencia <= 5 THEN 'Existencia baja'
ELSE 'Disponible'
END AS EstadoExistencia
FROM dbo.Producto AS p
ORDER BY p.Existencia;
| Nombre | Existencia | EstadoExistencia |
|---|---|---|
| Teclado compacto | 0 | Sin existencia |
| Disco externo 1 TB | 4 | Existencia baja |
| Soporte para monitor | 7 | Disponible |
La fila con existencia cero cumple también <= 5, pero conserva la primera coincidencia: Sin existencia.
Comparar un solo valor
Cuando todas las alternativas dependen de la misma columna podemos utilizar la forma simple:
SELECT
p.IdPedido,
p.Estado,
CASE p.Estado
WHEN 'Pendiente' THEN 'Requiere atención'
WHEN 'Confirmado' THEN 'En preparación'
WHEN 'Enviado' THEN 'En tránsito'
WHEN 'Cancelado' THEN 'Sin seguimiento'
ELSE 'Estado desconocido'
END AS DescripcionEstado
FROM dbo.Pedido AS p;
Esta forma compara por igualdad. Si necesitamos rangos, varias columnas o condiciones con AND y OR, utilizamos la primera sintaxis.
Utilizar CASE al ordenar
También podemos establecer una prioridad que no existe alfabéticamente:
SELECT
p.IdPedido,
p.Estado,
p.FechaPedido
FROM dbo.Pedido AS p
ORDER BY
CASE p.Estado
WHEN 'Pendiente' THEN 1
WHEN 'Confirmado' THEN 2
WHEN 'Enviado' THEN 3
ELSE 4
END,
p.FechaPedido;
Qué conviene comprobar
Los resultados de todas las ramas deben poder convertirse a un tipo compatible. La precedencia de tipos es el orden que utiliza SQL Server para decidir a qué tipo convertir valores diferentes. Mezclar números, fechas y textos sin considerarla puede provocar conversiones inesperadas o errores.
CASE tampoco garantiza que una expresión peligrosa quede protegida en todos los contextos. Si una operación puede fallar, como una conversión o una división, conviene hacerla segura directamente. TRY_CONVERT devuelve NULL cuando una conversión permitida no puede realizarse; NULLIF devuelve NULL cuando sus dos argumentos son iguales.