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
CASEexpresión - Buscado
CASEexpresió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