¿Qué es CASE en SQL?
SQL CASE es una expresión muy útil que proporciona lógica if-else a tus consultas SQL. Es un tema un poco más avanzado, pero lo necesitarás cuando prepares informes; aportará un gran valor a tus proyectos personales y profesionales.
La sentencia SQL CASE
es una herramienta de flujo de control que permite añadir lógica if-else a una consulta. En general, puede utilizar la sentencia CASE
en cualquier lugar que permita una expresión válida, por ejemplo, con las cláusulas SELECT
, WHERE
y GROUP BY
.
La expresión CASE
pasa por cada condición y devuelve un valor cuando se cumple la primera condición. Cuando una condición es verdadera, CASE
devolverá el resultado indicado. Si ninguna condición es verdadera, devolverá el valor de la cláusula ELSE
. Si no hay ELSE y ninguna condición es verdadera, devuelve NULL.
Ejemplo simple de SQL CASE
Esta es la sintaxis de la expresión SQL CASE
:
CASE WHEN condition_1 THEN result_1 WHEN condition_2 THEN result_2 ELSE else_result END |
En esta sintaxis, SQL CASE
hace coincidir el valor con condition_1
o condition_2
. Si se encuentra una coincidencia, la sentencia devolverá el resultado correspondiente (result_1
si el valor coincide con condition_1
o result_2
si coincide con condition_2
). Si el valor no coincide con ninguna de las dos condiciones, se devuelve else_result
. La sentencia ELSE
es opcional y proporciona una forma de capturar valores no especificados en las sentencias WHEN..THEN
. Por último, cada sentencia CASE
debe terminar con la palabra clave END
.
El tipo de datos del resultado de la sentencia SQL CASE
depende del contexto en el que se utilice. Por ejemplo, si la expresión CASE
se utiliza con cadenas CHAR, devuelve el resultado como una cadena CHAR. Si la expresión CASE
se utiliza en un contexto numérico, devuelve el resultado como un entero, un decimal o un valor real. El dominio de esta poderosa herramienta de flujo de control crea muchas nuevas oportunidades para recuperar y mostrar datos de forma creativa, como se muestra en este artículo sobre la adición de lógica a su consulta SQL con CASE.
Apliquemos la sentencia SQL CASE
a un ejemplo práctico. Imaginemos que tenemos una pequeña tienda de comestibles y que utilizamos una sencilla tabla de base de datos para hacer un seguimiento de nuestras existencias. La tabla stock
contiene el artículo, el precio del mismo y la cantidad de ese artículo que tenemos en stock.
Item | Price | Quantity |
---|---|---|
Bread | 1.59 | 23 |
Milk | 2.00 | 3 |
Coffee | 3.29 | 87 |
Sugar | 0.79 | 0 |
Eggs | 2.20 | 53 |
Apples | 1.99 | 17 |
¿Y si quisiéramos que una simple descripción acompañara a nuestros datos y proporcionara más contexto a nuestros informes? Esto se consigue fácilmente con CASE WHEN
:
SELECT Item, Price, CASE WHEN Price < 1.00 THEN 'Below $1.00' WHEN Price >= 1.00 THEN 'Greater or Equal to $1.00' END AS 'Price Description' FROM stock |
Primero, nuestra SELECT
declara que queremos recuperar los datos de nuestras columnas Item
y Price
. Lo siguiente es nuestra declaración CASE
. Cuando el Price
está por debajo de 1.00, devolvemos la cadena 'Below $1.00'. Cuando el Price
es mayor o igual a 1.00, queremos devolver la cadena 'Mayor o igual a $1.00'. Esto se aplica a cada valor de Price
en nuestra tabla.
También especificamos que los valores devueltos por la sentencia CASE WHEN
deben estar en una columna llamada Descripción del precio:
Item | Price | Price Description |
---|---|---|
Brea | 1.59 | Greater or Equal to $1.00 |
Milk | 2.00 | Greater or Equal to $1.00 |
Coffee | 3.29 | Greater or Equal to $1.00 |
Sugar | 0.79 | Below $1.00 |
Eggs | 2.20 | Greater or Equal to $1.00 |
Apples | 1.99 | Greater or Equal to $1.00 |
Ahí lo tenemos. Para cada fila en la que el Price
es inferior a 1,00, se devuelve la cadena 'Por debajo de 1,00'. Para los valores de Price
mayores o iguales a 1,00, se devuelve la cadena 'Mayor o igual a 1,00'. Los resultados se muestran en la columna Descripción del precio.
SQL CASE WHEN con ELSE
Si está utilizando ELSE
, esta sentencia debe venir después de cada condición CASE WHEN
que haya especificado. Supongamos que ahora queremos clasificar los diferentes precios de nuestra tabla en 3 categorías diferentes
- Artículos por debajo de $1.00.
- Artículos entre $1.00 y $3.00.
- Artículos por encima de $3.00.
Utilizaremos la sentencia ELSE
para manejar los valores de Price
por encima de 3.00:
SELECT Item, Price, CASE WHEN Price < 1.00 THEN 'Below $1.00' WHEN Price >= 1.00 AND Price <= 3.00 THEN 'Between $1.00 and $3.00' ELSE 'Above $3.00' END AS 'Price Description' FROM stock |
El Price
de cada fila se comprueba para ver si es igual o inferior a 1,00 o entre 1,00 y 3,00. Si entra en una de estas categorías, se devuelve la cadena correspondiente. Si Price
no es inferior a 3,00, se llega a la sentencia ELSE
. Nuestra sentencia ELSE
devuelve la cadena 'Por encima de 3,00'.
Por eso es importante el orden de las sentencias. SQL evalúa cada CASE
en orden, llegando finalmente a ELSE
si no se cumplen las condiciones.
Item | Price | Price Description |
---|---|---|
Bread | 1.59 | Between $1.00 and $3.00 |
Milk | 2.00 | Between $1.00 and $3.00 |
Coffee | 3.29 | Above $3.00 |
Sugar | 0.79 | Below $1.00 |
Eggs | 2.20 | Between $1.00 and $3.00 |
Apples | 1.99 | Between $1.00 and $3.00 |
Uso de múltiples CASOS
La razón principal por la que alguien puede elegir usar la sentencia SQL CASE
es que quieren evaluar múltiples condiciones. Quieren realizar una serie de comprobaciones y convertir los resultados en datos significativos, normalmente en forma de informe.
Supongamos que queremos generar un informe sencillo para nuestra stock
tabla. Nos dirá si el nivel de stock es alto, medio, bajo, o si está totalmente agotado. Esto se puede conseguir fácilmente utilizando CASE
:
SELECT Item, CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low' WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium' WHEN Quantity > 50 THEN 'High' ELSE 'Out Of Stock' END AS 'Stock Level' FROM stock |
Este es nuestro ejemplo más complejo hasta ahora. Vamos a desglosar esta consulta SQL.
Nuestro resultado tendrá dos columnas. La primera columna es Item
, con la que estamos seleccionando explícitamente:
SELECT Item |
La segunda columna es la columna de resultados generada por nuestras expresiones SQL CASE WHEN
, que estamos llamando Stock Level:
END AS 'Stock Level' |
Ahora vamos a desglosar cada condición, en el orden en que SQL las evaluaría.
Primero, SQL comprueba si el Quantity
es mayor que cero y menor o igual que 20.
CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low' |
Si el resultado es verdadero, se devuelve 'Low' y se comienza a evaluar la siguiente fila.
Si el resultado es falso, el evaluador mira la siguiente sentencia CASE
:
WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium' |
Quantity
se comprueba de nuevo si el valor es mayor que 20 y menor o igual que 50, devolviendo la cadena 'Media' si es el caso. Si no se cumple esta condición, se comprueba la siguiente:
WHEN Quantity > 50 THEN 'High' |
La última sentencia CASE
comprueba si Quantity
es mayor que 50, devolviendo la cadena 'Alta' si es así.
Hay otra situación que no está cubierta por nuestras diferentes sentencias CASE
. ¿Qué pasa si el Quantity
de un determinado Item
es 0? Mire de nuevo nuestras sentencias CASE
, en particular:
CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low' |
Comprobamos que Quantity
es mayor que 0, lo que significa que si es igual a 0, esta condición se evaluaría como falsa y la base de datos seguiría comprobando las demás sentencias CASE
. Hemos incluido la sentencia ELSE
en nuestra consulta SQL por esta razón:
ELSE 'Out Of Stock' |
Esto se ajusta a este escenario exacto. Si el Quantity
de un Item
es 0, el evaluador SQL llegará a nuestra sentencia ELSE
y devolverá 'Out of Stock'.
Al ejecutar esta consulta se obtiene el siguiente resultado:
Item | Stock Level |
---|---|
Bread | Medium |
Milk | Low |
Coffee | High |
Sugar | Out Of Stock |
Eggs | High |
Apples | Low |
Podemos ver que el azúcar tiene un Quantity
de 0, lo que hace que aparezca como "Sin existencias". Compare los otros valores de Quantity
en nuestra stock
tabla con el Stock Level
mostrado para asegurarse de que entiende cómo funcionan nuestras declaraciones CASE
.
Imagine lo útil que sería este informe si hubiera cientos de artículos. Un informe como éste podría enviarse diariamente a los responsables de compras, lo que les permitiría mantener los niveles de existencias de los artículos más populares.
CASO con valores NULL
Al utilizar CASE
, es posible que observe valores NULL no deseados en su conjunto de resultados. ¿Por qué aparecen estos valores y qué medidas puede tomar para eliminarlos? Los valores NULL aparecen cuando un valor no coincide con ninguna de las sentencias CASE
o ELSE
que usted declara. Veamos un ejemplo práctico que muestra cómo se pueden devolver valores NULL.
Imagine que excluimos la sentencia ELSE
de nuestro ejemplo anterior. ¿Cómo afectaría a nuestros resultados? Veamos la consulta anterior, esta vez sin la sentencia ELSE
:
SELECT Item, CASE WHEN Quantity > 0 AND Quantity <= 20 THEN 'Low' WHEN Quantity > 20 AND Quantity <= 50 THEN 'Medium' WHEN Quantity > 50 THEN 'High' END AS 'Stock Level' FROM stock |
Los resultados se verían así. Preste especial atención al nivel de existencias de azúcar:
Item | Stock Level |
---|---|
Bread | Medium |
Milk | Low |
Coffee | High |
Sugar | NULL |
Eggs | High |
Apples | Low |
Sin ELSE
para manejar la situación de que Quantity
sea cero, nuestra consulta devuelve un NULL.
Si tiene un valor NULL no deseado en sus resultados de CASE WHEN
, puede tener un escenario que no está cubierto por sus condiciones de CASE WHEN
y ELSE
.
Agrupar por con CASE
Como se mencionó anteriormente, puede utilizar la expresión SQL CASE
con GROUP BY
. Examinemos un ejemplo práctico de esto.
Imaginemos que queremos agrupar los artículos en función de su precio y, al mismo tiempo, mostrar el precio mínimo y máximo de los grupos de bajo y alto coste. Esto requiere el uso de las funciones de agregación MIN()
y MAX()
. La sentencia GROUP BY
se utiliza a menudo para agrupar los datos resultantes por una o más columnas, y a menudo específicamente con funciones agregadas. Aquí hay un ejemplo de cómo se utiliza GROUP BY junto con las funciones de agregado que puede leer para obtener más información. Vamos a desglosar la consulta SQL que aparece a continuación para mostrar cómo se puede conseguir el conjunto de resultados que deseamos:
SELECT CASE WHEN Price >= 2.00 THEN 'High Price Item' WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item' END AS PriceLevel, Min (Price) as MinimumPrice, Max (Price) as MaximumPrice FROM stock GROUP BY CASE WHEN Price >= 2.00 THEN 'High Price Item' WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item' END |
Primero, analicemos la sentencia CASE
. Es similar al ejemplo anterior.
CASE WHEN Price >= 2.00 THEN 'High Price Item' WHEN Price > 0 AND Price < 2.00 THEN 'Low Price Item' END AS PriceLevel |
Si Price
es mayor o igual a 2,00, el artículo se clasifica como de precio alto. Si Price
es mayor que 0 pero menor que 2,00, el artículo es de precio bajo. Estos valores de cadena se almacenan y se muestran en la columna PriceLevel
, como se especifica en el alias END AS
.
Utilizamos las funciones de agregación MIN()
y MAX()
en nuestra columna Price
. De este modo, obtenemos los valores más bajos y más altos de Price
de los elementos de nuestra tabla.
Utilizamos nuestra cláusula GROUP BY
para aplicar estas funciones agregadas a nuestras dos categorías de niveles de precios altos y bajos. (No se preocupe si esto parece complicado; dominar GROUP BY
requiere mucha práctica. Consulte nuestra pista Ejercicio de SQL para ver ejercicios interactivos que perfeccionan su técnica de GROUP BY y otras habilidades SQL).
La ejecución de esta consulta SQL devuelve el siguiente conjunto de resultados:
PriceLevel | MinimumPrice | MaximumPrice |
---|---|---|
High Price Item | 2.00 | 3.29 |
Low Price Item | 0.79 | 1.99 |
Estos son exactamente los resultados que queríamos. Ahora podemos ver claramente el precio mínimo y máximo de cada una de las categorías de artículos definidas en nuestra sentencia SQL CASE WHEN
. Consulte nuestra tabla stock
y observe qué artículos individuales están vinculados a los valores mostrados para MinimumPrice
y MaximumPrice
. Si añadiéramos un nuevo artículo a nuestra tabla stock
tabla que cuesta 4,00 dólares, vería que el MaximumPrice
del "Artículo de precio alto" aumenta a 4,00.
SQL CASE y consultas complejas reutilizables
El uso de SQL CASE
le permitirá escribir consultas complejas que realicen una serie de acciones. Acabamos de mostrarle cómo utilizar CASE WHEN
con SELECT
. Como se muestra en este artículo sobre el uso de CASE con sentencias de modificación de datos, el caso CASE WHEN
también se puede utilizar con INSERT
, UPDATE
, y DELETE
. Esto da lugar a consultas muy reutilizables que pueden implementarse para informes o aplicaciones. Si estás interesado en aprender a crear informes personalizados de alto valor, te recomiendo el curso completo de LearnSQL.es sobre la creación de informes SQL.