Agregación condicional se utiliza cuando se necesita agregar valores (por ejemplo, suma o conteo) bajo diferentes condiciones en una sola consulta. Históricamente, para lograr estos objetivos, los desarrolladores de SQL tenían que escribir múltiples subconsultas o hacer uniones y agrupaciones por separado para cada categoría, lo que resultaba en un código menos legible y menos eficiente.
El problema radicaba en la dificultad de calcular múltiples agregados simultáneamente con diferentes condiciones — cada agregado por lo general requiere filtrado, y la simple aplicación de SUM() o COUNT() no toma en cuenta la condición necesaria dentro de la función de agregado.
Solución — el uso de la construcción CASE dentro de la función de agregado, lo que permite "dividir" los agregados bajo diferentes condiciones al vuelo, sin recurrir a múltiples uniones:
Ejemplo de código:
SELECT department, SUM(CASE WHEN status = 'approved' THEN amount ELSE 0 END) AS approved_sum, SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS pending_sum, COUNT(CASE WHEN status = 'rejected' THEN 1 END) AS rejected_count FROM payments GROUP BY department;
Características clave:
¿Se puede prescindir de la construcción CASE para la agregación condicional?
La respuesta incorrecta — utilizar WHERE en la consulta directamente junto con la función de agregado. En realidad, WHERE filtra las filas antes de la agregación, no dentro de cada columna de agregado.
Ejemplo de código (método incorrecto):
SELECT COUNT(*) FROM payments WHERE status = 'approved'; SELECT COUNT(*) FROM payments WHERE status = 'pending';
Estos consultas no se pueden juntar en una sola línea de resultados bajo diferentes condiciones sin CASE.
¿Qué sucederá si se usa NULL dentro de la expresión condicional?
Si CASE no devuelve un valor alternativo, por defecto será NULL, y la función de agregado ignorará NULL.
Ejemplo de código:
SUM(CASE WHEN status = 'approved' THEN amount END) -- Si el estado no es 'approved', entonces NULL, y la fila se ignora en SUM
¿Se puede usar IF en lugar de CASE?
En algunos dialectos de SQL (por ejemplo, MySQL) es posible, pero dicho código se vuelve no portable entre diferentes bases de datos. En consultas universales, siempre use CASE.
Un analista intentó calcular las sumas por cada estado, escribiendo varias subconsultas. El informe externo se volvió complicado, y agregar nuevos estados requería reescribir el código cada vez.
Pros:
Un desarrollador utilizó CASE en una consulta general, creando un informe universal con la capacidad de ampliación para nuevos estados a través de una simple edición de una consulta.
Pros: