En SQL, el CASE
evalúa una lista de condiciones y devuelve una de varias expresiones de resultado posibles.
De alguna manera, el SQL CASE
declaración es similar a IF...ELSE
declaración en la que nos permite verificar una condición dada y devolver un resultado diferente dependiendo del resultado.
¿Es un CASE
? Declaración o CASE
¿Expresión?
En SQL, a veces se hace referencia a las cosas como una "declaración" cuando, de hecho, son otra cosa. El SQL “CASE
declaración” es un buen ejemplo (¡perdón por el juego de palabras!).
El CASE
declaración se denomina en el estándar SQL (ISO/IEC 9075) como CASE
expresión . Su propósito es "especificar un valor condicional".
Sin embargo, algunos DBMS distinguen entre CASE
declaración y el CASE
expresión, y tienen una sintaxis ligeramente diferente para cada uno. Por ejemplo, tanto MySQL como MariaDB proporcionan el CASE
declaración y el CASE
operador como dos características distintas, cada una con una sintaxis ligeramente diferente.
CASE
Formatos
En SQL, hay dos formatos de CASE
expresión:
- Simple
CASE
expresión - Buscado
CASE
expresión
A continuación se muestran ejemplos de cada uno.
El CASE
sencillo Expresión
El CASE
simple expresión compara una expresión con un conjunto de expresiones simples para determinar el resultado.
Ejemplo:
DECLARE @animal VARCHAR(40);
SET @animal = 'Cow';
SELECT
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END;
Resultado:
Grass
Este ejemplo se hizo en MySQL, pero el CASE
real expresión debería funcionar en la mayoría de los principales RDBMS.
En este ejemplo, mi CASE
expresión es parte de un SELECT
declaración. Comprueba tres condiciones y tiene un ELSE
para atender lo que no esté contemplado en las tres condiciones.
En este caso, el animal Cow
coincide con el tercer WHEN
expresión, y la expresión proporcionada por su THEN
es devuelto.
Para ser claros, el CASE
real expresión es esta parte:
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
¿Qué CASE
lo que hace es comprobar el valor de cada WHEN
expresión contra la expresión de entrada. En este ejemplo, @animal
variable es la expresión de entrada. Por lo tanto, está comprobando el valor de cada WHEN
expresión contra el @animal
variables.
Cuando/si encuentra una coincidencia, devuelve la expresión proporcionada por el THEN
correspondiente .
Mi ejemplo usa tres WHEN
expresiones, pero podría haber usado más y podría haber usado menos, dependiendo de los requisitos.
El CASE
buscado Expresión
El CASE
buscado expresión evalúa un conjunto de expresiones booleanas para determinar el resultado.
Este es un ejemplo de un CASE
buscado expresión.
DECLARE @score int;
SET @score = 7;
SELECT
CASE
WHEN @score > 8 THEN 'Congratulations!'
WHEN @score > 5 AND @score < 8 THEN 'Well done!'
ELSE 'Try harder next time'
END;
Resultado:
Well done!
El CASE
buscado expresión no tiene una expresión de entrada como el simple CASE
expresión.
Lo recordarás en nuestro sencillo CASE
expresión, comenzó con CASE
@animal
, y por lo tanto sabíamos que el WHEN
todas las expresiones se evaluaron contra el valor de @animal
.
Con el CASE
buscado expresión, no proporcionamos una expresión de entrada al principio como esa. En cambio, cada WHEN
expresión incluye una expresión booleana contra la cual se evaluará.
Un ejemplo de base de datos
Aquí hay un ejemplo que demuestra cómo CASE
expresión se puede utilizar dentro de una consulta de base de datos.
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultado:
+---------------+------------+------------+ | Name | Population | Size | +---------------+------------+------------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | Small City | | San Jose | 894943 | Small City | | Indianapolis | 791926 | Small City | | San Francisco | 776733 | Small City | | Jacksonville | 735167 | Small City | | Columbus | 711470 | Small City | | Austin | 656562 | Small City | | Baltimore | 651154 | Small City | | Memphis | 650100 | Small City | | Milwaukee | 596974 | Small City | | Boston | 589141 | Small City | +---------------+------------+------------+
Este ejemplo utiliza un CASE
buscado expresión para evaluar los resultados de la Population
columna de la City
mesa.
ELSE
es opcional
El ELSE
argumento es opcional. Si omitimos el ELSE
, y ninguna de las condiciones se activa, el resultado es NULL
.
Esto es lo que sucede cuando omitimos ELSE
cláusula del ejemplo anterior:
USE World;
SELECT
Name,
Population,
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
END AS Size
FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultado:
+---------------+------------+-----------+ | Name | Population | Size | +---------------+------------+-----------+ | New York | 8008278 | Huge City | | Los Angeles | 3694820 | Huge City | | Chicago | 2896016 | Huge City | | Houston | 1953631 | Big City | | Philadelphia | 1517550 | Big City | | Phoenix | 1321045 | Big City | | San Diego | 1223400 | Big City | | Dallas | 1188580 | Big City | | San Antonio | 1144646 | Big City | | Detroit | 951270 | NULL | | San Jose | 894943 | NULL | | Indianapolis | 791926 | NULL | | San Francisco | 776733 | NULL | | Jacksonville | 735167 | NULL | | Columbus | 711470 | NULL | | Austin | 656562 | NULL | | Baltimore | 651154 | NULL | | Memphis | 650100 | NULL | | Milwaukee | 596974 | NULL | | Boston | 589141 | NULL | +---------------+------------+-----------+
CASE
en un UPDATE
Declaración
Agreguemos una columna a la City
tabla del ejemplo anterior:
ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10;
Así es como se ve ahora:
+----+----------------+-------------+---------------+------------+------+ | ID | Name | CountryCode | District | Population | Size | +----+----------------+-------------+---------------+------------+------+ | 1 | Kabul | AFG | Kabol | 1780000 | NULL | | 2 | Qandahar | AFG | Qandahar | 237500 | NULL | | 3 | Herat | AFG | Herat | 186800 | NULL | | 4 | Mazar-e-Sharif | AFG | Balkh | 127800 | NULL | | 5 | Amsterdam | NLD | Noord-Holland | 731200 | NULL | | 6 | Rotterdam | NLD | Zuid-Holland | 593321 | NULL | | 7 | Haag | NLD | Zuid-Holland | 440900 | NULL | | 8 | Utrecht | NLD | Utrecht | 234323 | NULL | | 9 | Eindhoven | NLD | Noord-Brabant | 201843 | NULL | | 10 | Tilburg | NLD | Noord-Brabant | 193238 | NULL | +----+----------------+-------------+---------------+------------+------+
No hemos insertado ningún dato en el nuevo Size
columna, por lo que devuelve NULL
en cada fila.
Ahora podemos usar un CASE
expresión para actualizar el Size
columna con un valor que depende del valor en la Population
columna:
UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END;
Ahora seleccionemos datos de la tabla:
SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Resultado:
+------+---------------+-------------+---------------+------------+------------+ | ID | Name | CountryCode | District | Population | Size | +------+---------------+-------------+---------------+------------+------------+ | 3793 | New York | USA | New York | 8008278 | Huge City | | 3794 | Los Angeles | USA | California | 3694820 | Huge City | | 3795 | Chicago | USA | Illinois | 2896016 | Huge City | | 3796 | Houston | USA | Texas | 1953631 | Big City | | 3797 | Philadelphia | USA | Pennsylvania | 1517550 | Big City | | 3798 | Phoenix | USA | Arizona | 1321045 | Big City | | 3799 | San Diego | USA | California | 1223400 | Big City | | 3800 | Dallas | USA | Texas | 1188580 | Big City | | 3801 | San Antonio | USA | Texas | 1144646 | Big City | | 3802 | Detroit | USA | Michigan | 951270 | Small City | | 3803 | San Jose | USA | California | 894943 | Small City | | 3804 | Indianapolis | USA | Indiana | 791926 | Small City | | 3805 | San Francisco | USA | California | 776733 | Small City | | 3806 | Jacksonville | USA | Florida | 735167 | Small City | | 3807 | Columbus | USA | Ohio | 711470 | Small City | | 3808 | Austin | USA | Texas | 656562 | Small City | | 3809 | Baltimore | USA | Maryland | 651154 | Small City | | 3810 | Memphis | USA | Tennessee | 650100 | Small City | | 3811 | Milwaukee | USA | Wisconsin | 596974 | Small City | | 3812 | Boston | USA | Massachusetts | 589141 | Small City | +------+---------------+-------------+---------------+------------+------------+
CASE
en un INSERT
Declaración
Supongamos que tenemos la siguiente tabla en una base de datos de SQL Server:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
Insertemos una nueva fila en esa tabla. Pero usemos el CASE
expresión para insertar el valor apropiado en Dinner
columna, dependiendo del valor en GoodDog
columna:
DECLARE @DogName nvarchar(60), @GoodDog bit;
SET @DogName = 'Lazy';
SET @GoodDog = 0;
INSERT INTO Dogs ( DogName, GoodDog, Dinner )
VALUES (
@DogName,
@GoodDog,
CASE @GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
);
Aquí, el CASE
expresión evaluó el valor de una variable que acabábamos de establecer y luego insertó el valor apropiado en el Dinner
columna.
Ahora revisemos la tabla nuevamente:
SELECT * FROM Dogs;
Resultado:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Podemos ver que el valor apropiado está en Dinner
columna.
CASE
en un ORDER BY
Cláusula
El CASE
expresión se puede utilizar en cualquier declaración o cláusula que permita una expresión válida. Por lo tanto, puede usarlo en declaraciones como SELECT
, UPDATE
, DELETE
y SET
, y en cláusulas como IN
, WHERE
, ORDER BY
, GROUP BY
, y HAVING
.
Usando un CASE
expresión en el ORDER BY
de una declaración La cláusula puede ser útil cuando desea hacer una excepción especial para ciertos valores al ordenar sus resultados.
Supongamos que ejecutamos la siguiente consulta en una tabla que contiene géneros musicales.
SELECT Genre
FROM Genres
ORDER BY Genre ASC;
Resultado:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
Aquí, ordenamos los resultados por Genre
columna, en orden ascendente.
Esto está bien excepto por una cosa. El género llamado Other
. ¿No sería bueno si pudiéramos mover Other
hasta el fondo?
Podemos lograr esto con el CASE
expresión tomando la consulta anterior y modificándola de la siguiente manera.
SELECT Genre
FROM Genres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultado:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Pop | | Punk | | Rap | | Rock | | Other | +---------+
El COALESCE()
y NULLIF()
Funciones
Dependiendo del escenario podemos usar funciones como COALESCE()
y NULLIF()
como atajo, en lugar de usar CASE
expresión.
Estas dos funciones son estándar de SQL y funcionan de la siguiente manera:
NULLIF (V1, V2)
Es equivalente a:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Y:
COALESCE (V1, V2)
Es equivalente a:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
También:
COALESCE (V1, V2, ..., Vn)
Es equivalente a:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END