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. No controla el flujo general del procedimiento: 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.

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. Mezclar números, fechas y textos sin considerar la precedencia de tipos 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 con construcciones como TRY_CONVERT o NULLIF.

Relacionado con

  • COALESCE e ISNULL: sustituyen valores nulos sin expresar varias condiciones.
  • ORDER BY: puede utilizar una expresión CASE para definir prioridades.
  • UPDATE: puede asignar valores diferentes según cada fila.
  • Operadores lógicos: permiten construir las condiciones de cada rama.