Declaración SQL CASE WHEN: sintaxis, ejemplos reales y errores comunes

  1. Inicio
  2. Blog
  3. Bases de datos y SQL

Bases de datos y SQL

Declaración SQL CASE WHEN: Sintaxis, ejemplos reales y errores comunes

CASO CUANDO es cómo se escribe la lógica si-entonces en SQL. Aprenda ambos formularios, luego utilícelos para etiquetas, informes de estilo dinámico, clasificación personalizada y actualizaciones seguras, evitando al mismo tiempo las trampas de orden y NULL.

8 min de lectura
Sentencia SQL CASE WHEN: sintaxis, ejemplos reales y errores comunes

Puntos clave

  • CASE devuelve un valor basado en la primera condición que es verdadera.
  • Ponga primero las condiciones más específicas, o es posible que nunca se alcancen las posteriores.
  • Sin ELSE, las filas no coincidentes devuelven NULL.
  • Dentro de SUM o COUNT, CASE convierte una consulta en un informe compacto de estilo dinámico.

La mayoría de los informes necesitan algo de lógica: etiquetar los pedidos como grandes o pequeños, contar los pedidos pagados y pendientes uno al lado del otro o mostrar primero los artículos urgentes. SQL CASE WHEN maneja todo esto directamente dentro de una consulta y funciona en todas las bases de datos principales.

Ejecutamos todas las consultas aquí en SQLite 3.50 y los resultados mostrados provienen de esa ejecución. CASE es parte del SQL estándar, por lo que se comporta de la misma manera en PostgreSQL, MySQL, SQL Server y Oracle para estos ejemplos.

¿Qué es CASO CUANDO?

CASE es una expresión, no un comando separado. Evalúa las condiciones en orden y devuelve un valor, por lo que puede ir a cualquier lugar donde se permita un valor: en SELECT, WHERE, GROUP BY, ORDER BY o dentro de funciones. Siempre termina en END.

CASE
  WHEN condition1 THEN result1
  WHEN condition2 THEN result2
  ELSE fallback
END

La tabla de muestra

CREATE TABLE orders (id INT, customer TEXT, total INT, status TEXT);

INSERT INTO orders VALUES
 (1,'Asha',1200,'paid'), (2,'Ben',300,'pending'),
 (3,'Asha',800,'paid'), (4,'Chitra',2500,'shipped'),
 (5,'Dev',150,'cancelled'), (6,'Ben',NULL,'pending');

Observe que el pedido 6 no tiene total. Esa disputa importa más adelante.

CASO buscado

Esta es la forma más flexible, ya que cada WHEN tiene una condición propia y completa:

SELECT id, total,
       CASE
         WHEN total >= 1000 THEN 'large'
         WHEN total >= 500 THEN 'medium'
         ELSE 'small'
       END AS size
FROM orders;

-- 1 | 1200 | large
-- 2 |  300 | small
-- 3 |  800 | medium
-- 4 | 2500 | large
-- 5 |  150 | small
-- 6 | NULL | small

Mira la última fila. El pedido 6 no tiene total, pero está etiquetado como “pequeño”. Ambas comparaciones con NULL no eran ciertas, por lo que se optó por ELSE. Mostramos cómo solucionar este problema en la sección NULL. Asigne siempre un nombre al resultado usando AS, o puede obtener un nombre de columna extraño.

CASO sencillo

Cuando compara una columna con valores fijos, la forma más corta se lee mejor:

SELECT id,
       CASE status
         WHEN 'paid' THEN 'Complete'
         WHEN 'shipped' THEN 'Complete'
         WHEN 'pending' THEN 'Waiting'
       END AS label
FROM orders;

-- 1 | Complete
-- 2 | Waiting
-- 3 | Complete
-- 4 | Complete
-- 5 | NULL
-- 6 | Waiting
Formulario compara ¿Se pueden usar rangos? Lo mejor para
Sencillo Una expresión para la igualdad No Asignación de códigos a etiquetas
buscado Cualquier condición por sucursal si Rangos, múltiples columnas, controles NULL

El orden importa

CASE se detiene en la primera condición verdadera y este es el error lógico más común. Cambie las dos condiciones de nuestra consulta anterior:

SELECT id, total,
       CASE
         WHEN total >= 500 THEN 'medium'
         WHEN total >= 1000 THEN 'large'
         ELSE 'small'
       END AS size
FROM orders WHERE id IN (1, 4);

-- 1 | 1200 | medium
-- 4 | 2500 | medium

Ahora nada puede ser “grande”. Un total de 2500 es también al menos 500, por lo que la primera rama gana y la segunda nunca se alcanza. No aparece ningún error, sólo etiquetas incorrectas. Para rangos, coloque primero la condición más restrictiva o escriba rangos completos, como total >= 500 AND total < 1000.

¿Qué pasa sin MÁS?

En nuestro ejemplo de CASO simple anterior, el pedido 5 se canceló y ninguna sucursal lo manejó, por lo que el resultado fue NULL. A veces eso es exactamente lo que quieres, como se muestra en la siguiente sección. Pero al crear etiquetas, un ELSE 'other' claro suele ser mejor, ya que hace visibles los valores inesperados en lugar de dejar espacios en blanco en un informe.

Consejo: Todas las ramas deben devolver el mismo tipo. Combinar texto y números funciona de manera flexible en SQLite, pero las bases de datos más estrictas, como PostgreSQL, generarán un error o intentarán convertir valores de formas no previstas.

Informes estilo pivote con SUM

Este es uno de los patrones más útiles en SQL cotidiano. Al agrupar CASE en un agregado, las filas se convierten en columnas, con una fila por cliente:

SELECT customer,
       SUM(CASE WHEN status = 'paid' THEN total ELSE 0 END) AS paid,
       SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_orders
FROM orders
GROUP BY customer
ORDER BY customer;

-- Asha   | 2000 | 0
-- Ben    |    0 | 2
-- Chitra |    0 | 0
-- Dev    |    0 | 0

Una consulta ahora proporciona tanto los ingresos pagados como el número de pedidos pendientes, sin necesidad de consultas ni uniones por separado. El patrón funciona en casi todas las bases de datos, a diferencia de la sintaxis dedicada PIVOT que sólo algunas ofrecen. Si GROUP BY es nuevo para usted, lea SQL GROUP BY y HAVING.

Conteos condicionales

COUNT omite NULL, por lo que un CASE sin ELSE cuenta solo las filas que coinciden:

SELECT COUNT(*) AS all_orders,
       COUNT(CASE WHEN status = 'paid' THEN 1 END) AS paid_orders,
       COUNT(CASE WHEN total >= 1000 THEN 1 END) AS large_orders
FROM orders;

-- 6 | 2 | 2

Tenga cuidado: si agrega ELSE 0 dentro de COUNT, cada fila se cuenta, porque 0 no es NULL. Utilice ELSE 0 con SUM y omítalo con COUNT. PostgreSQL y SQLite también admiten COUNT(*) FILTER (WHERE ...), que se lee muy bien, pero no está disponible en todas partes.

Agrupar por un CASO

Puede crear sus propios depósitos y luego resumirlos:

SELECT CASE WHEN total >= 1000 THEN 'large' ELSE 'other' END AS bucket,
       COUNT(*)
FROM orders
GROUP BY bucket
ORDER BY bucket;

-- large | 2
-- other | 4

La agrupación por alias funciona en SQLite, PostgreSQL y MySQL. SQL Server no lo permite, por lo que tendría que repetir la expresión completa o colocar la consulta en un CTE o subconsulta primero.

Clasificación personalizada con ORDER BY

El orden alfabético rara vez es lo que quiere una empresa. CASE le permite definir su propio orden:

SELECT id, status FROM orders
ORDER BY CASE status
           WHEN 'pending' THEN 1
           WHEN 'paid' THEN 2
           ELSE 3
         END, id;

-- 2 | pending
-- 6 | pending
-- 1 | paid
-- 3 | paid
-- 4 | shipped
-- 5 | cancelled

Los pedidos pendientes van primero, lo cual resulta útil para una cola de trabajo. La segunda columna de clasificación, id, mantiene las filas en un orden predecible dentro de cada grupo.

CASO en ACTUALIZACIÓN

CASE permite que una declaración aplique diferentes cambios a diferentes filas. Aquí, las pequeñas órdenes pendientes se marcan para su revisión:

UPDATE orders
SET status = CASE
               WHEN status = 'pending' AND total < 500 THEN 'review'
               ELSE status
             END;

SELECT id, status FROM orders WHERE customer = 'Ben';

-- 2 | review
-- 6 | pending

El ELSE status mantiene las demás filas sin cambios. Dejarlo fuera es peligroso, porque las filas no coincidentes se establecerían en NULL. Sin una cláusula WHERE, esta declaración también afecta a cada fila, por lo que en tablas grandes agregue un filtro y considere incluir el cambio en una transacción para que pueda verificar el resultado antes de confirmar. Observe también que el orden 6 no cambió, porque su total NULL no satisfizo total < 500.

trampas NULL

NULL causa dos problemas distintos con CASE. Primero, la forma simple compara usando igualdad, y nada es igual a NULL, ni siquiera NULL en sí:

SELECT CASE NULL WHEN NULL THEN 'matched' ELSE 'not matched' END;

-- not matched

Entonces CASE col WHEN NULL nunca coincide. Utilice el formulario buscado con IS NULL en su lugar. En segundo lugar, como vimos con el orden 6, un valor NULL pasa por alto las comparaciones y aterriza en ELSE. La solución es comprobarlo primero:

SELECT id,
       CASE
         WHEN total IS NULL THEN 'unknown'
         WHEN total >= 1000 THEN 'large'
         ELSE 'other'
       END AS size
FROM orders WHERE id IN (1, 2, 6);

-- 1 | large
-- 2 | other
-- 6 | unknown

El pedido 6 ahora recibe una etiqueta honesta. Nuestra guía sobre valores NULL de SQL cubre este comportamiento en su totalidad.

CASE frente a otras opciones

Opción Trabaja en Úselo cuando
CASO Todas las bases de datos principales Quieres lógica portátil
FUSIONAR Todas las bases de datos principales Sólo necesitas un respaldo para NULL
IF() mysql Una simple elección bidireccional
IIF() Servidor SQL, SQLite Una simple elección bidireccional
DECODE() Oráculo Código de Oracle más antiguo
tabla de búsqueda Todos El mapeo es largo o cambia con frecuencia.

Esa última opción merece una reflexión. Si un CASE crece hasta treinta ramas y aparece en cinco consultas, mueva la asignación a una tabla y únase a ella. Entonces un cambio es una actualización de una sola fila, en lugar de un cambio de código en cinco lugares.

Errores comunes

  • Orden de condiciones incorrecto. Una condición amplia primero oculta las más estrechas.
  • Olvidar END. Este es el error de sintaxis más frecuente.
  • Usando WHEN NULL. Nunca coincide, así que usa WHEN col IS NULL.
  • Agregando ELSE 0 dentro de COUNT. Cuenta todas las filas.
  • Omitir ELSE en una ACTUALIZACIÓN. Puede borrar valores con NULL.
  • Filtrar por CASO en WHERE. Puede detener el uso de un índice. Consulte nuestra guía para optimización de consultas SQL.

Conclusión

CASE CUANDO es una pequeña característica que hace mucho trabajo. Recuerde tres reglas: la primera rama verdadera gana, las filas no coincidentes se vuelven NULL sin un ELSE y NULL necesita su propia verificación. Para practicar, tome un informe que esté creando actualmente con varias consultas e intente generarlo como una sola consulta usando SUM(CASE ...).

Preguntas frecuentes

¿Qué hace CASE CUANDO en SQL?

Agrega lógica si-entonces a una consulta. SQL verifica cada condición en orden y devuelve el valor de la primera que es verdadera, o el valor ELSE si no lo es.

¿Qué sucede si no hay ELSE en una declaración CASE?

Las filas que no coinciden con ninguna condición devuelven NULL. Esto es útil dentro de COUNT, pero en etiquetas y actualizaciones puede provocar espacios en blanco o pérdida de datos.

¿Puedo usar CASE en una cláusula WHERE?

Sí, porque es una expresión. Sin embargo, las condiciones simples AND y OR suelen ser más claras y es más probable que utilicen un índice.

¿Cuál es la diferencia entre CASE simple y buscado?

CASO simple compara una expresión con valores fijos para determinar la igualdad. El CASO buscado tiene una condición completa en cada CUÁNDO, por lo que puede manejar rangos y comprobaciones NULL.

¿Se pueden anidar las declaraciones CASE?

Sí, un CASO puede aparecer dentro de otro. Sin embargo, el anidamiento profundo resulta difícil de leer, así que considere combinar condiciones con AND o usar una tabla de búsqueda.

sigue aprendiendo

Trabajar con Stack Quora

¿Necesitas ayuda con pruebas, WordPress o SEO?

Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.

Sigue leyendo

Más guías sobre testing, IA y desarrollo moderno

¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.

Inteligencia artificial

Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas

Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…

Leer artículo →
DevOps

Explicación de las variables de entorno: archivos .env, secretos y configuración bien hechos

Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…

Leer artículo →
Desarrollo de software

Explicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429

La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …

Leer artículo →
Automatización de pruebas

Burlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan

Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…

Leer artículo →
Pruebas de software

Explicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%

Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…

Leer artículo →
Bases de datos y SQL

DELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno

DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…

Leer artículo →
Bases de datos y SQL

Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…

Leer artículo →
Desarrollo de software

Interfaz TypeScript versus tipo: diferencias reales, probadas con el compilador

Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…

Leer artículo →
Desarrollo de software

Python *args y **kwargs explicados: funciones flexibles con ejemplos claros

Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…

Leer artículo →
Desarrollo de software

Funciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas

Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…

Leer artículo →
Inteligencia artificial

¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar

¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…

Leer artículo →
DevOps

Monitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos

Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…

Leer artículo →
DevOps

Docker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta

Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…

Leer artículo →
Automatización de pruebas

TDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una

TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …

Leer artículo →
Pruebas de software

Pruebas de Aceptación de Usuario (UAT): Proceso, Lista de Verificación y Ejemplos Reales

Explicación de las pruebas de aceptación del usuario: quién las ejecuta, en qué se diferencia del control de calidad, un proceso de siete pasos, una…

Leer artículo →
Bases de datos y SQL

Valores NULL de SQL explicados: IS NULL, COALESCE, NULLIF y las trampas que se deben evitar

Los valores NULL de SQL se explican con las consultas que ejecutamos: lógica de tres valores, IS NULL, COALESCE, NULLIF, cómo los agregados, las uni…

Leer artículo →
Bases de datos y SQL

Declaración SQL CASE WHEN: sintaxis, ejemplos reales y errores comunes

CASO SQL CUANDO se explicó con las consultas que ejecutamos: formularios simples y buscados, orden de condiciones, pivotes con SUMA, trucos COUNT, c…

Leer artículo →
Desarrollo de software

¿Qué es JWT? Tokens web JSON explicados con un ejemplo práctico

¿Qué es JWT? JSON Web Tokens explicó: las tres partes, un token creado y manipulado en el código que ejecutamos, JWT vs sesiones, almacenamiento, to…

Leer artículo →
Desarrollo de software

Explicación del bucle de eventos de JavaScript: pila de llamadas, microtareas y temporizadores con ejemplos

El bucle de eventos de JavaScript explicado con el código que ejecutamos: pila de llamadas, colas de tareas y microtareas, por qué setTimeout 0 no e…

Leer artículo →
Desarrollo de software

Explicación de los generadores y el rendimiento de Python: ahorre memoria con ejemplos reales

Los generadores de Python y el rendimiento se explican con el código que ejecutamos: cómo se pausan y reanudan, midieron el ahorro de memoria, canal…

Leer artículo →
Inteligencia artificial

¿Qué son las incrustaciones? Los vectores y la similitud del coseno se explican de forma sencilla

¿Qué son las incrustaciones? Una guía en lenguaje sencillo sobre vectores, similitud de cosenos y búsqueda semántica, con un pequeño ejemplo que eje…

Leer artículo →
DevOps

Implementación azul-verde versus implementación canaria: diferencias, compensaciones y cómo elegir

Explicación de la implementación azul-verde versus canaria: cómo funciona cada uno, costo, riesgo y reversión, agrupación estable de usuarios que pr…

Leer artículo →
Desarrollo de software

Git merge vs rebase: diferencias, ejemplos y cuándo usar cada uno

Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.

Leer artículo →
Desarrollo de software

List comprehension en Python: sintaxis, ejemplos y cuándo evitarla

List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.

Leer artículo →