En SQL Server, el T-SQL CASE
expresión es una expresión escalar que devuelve un valor basado en lógica condicional. Evalúa una lista de condiciones y devuelve un valor, basado en el resultado de esas condiciones..
De alguna manera, el CASE
de SQL Server expresión es similar a IF...ELSE
. Sin embargo, CASE
le permite verificar múltiples condiciones, mientras que IF...ELSE
no.
Además, en SQL Server, IF...ELSE
es una palabra clave de lenguaje de control de flujo, mientras que CASE
no es. El CASE
expresión no se puede utilizar para controlar el flujo de ejecución de instrucciones T-SQL, bloques de instrucciones, funciones definidas por el usuario y procedimientos almacenados.
Las 2 formas de expresión CASE
Hay dos formas de CASE
expresión en SQL Server:
- Simple
CASE
expresión - Buscado
CASE
expresión
Estos se explican con ejemplos a continuación.
Forma 1:la expresión CASE simple
El CASE
simple expresión compara una expresión con un conjunto de expresiones simples para determinar el resultado.
Aquí hay un ejemplo básico para demostrar cómo un CASE
expresión funciona en SQL Server.
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END
Resultado:
+-----------+ | Company | |-----------| | Visa | +-----------+
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 tablero de cotizaciones V
coincide con el tercer WHEN
expresión, y la expresión proporcionada por THEN
es devuelto.
Para ser claros, el CASE
real expresión es esta parte:
CASE @stock_ticker
WHEN 'AAPL' THEN 'Apple'
WHEN 'FB' THEN 'Facebook'
WHEN 'MA' THEN 'Mastercard'
WHEN 'V' THEN 'Visa'
ELSE 'Not in the portfolio'
END
¿Qué CASE
lo que hace es comprobar el valor de cada WHEN
expresión contra la expresión de entrada. En mi ejemplo, @stock_ticker
variable es la expresión de entrada. Por lo tanto, está comprobando el valor de cada WHEN
expresión contra el @stock_ticker
variables.
Cuando/si encuentra una coincidencia, devuelve la expresión proporcionada por THEN
.
Mi ejemplo usa tres WHEN
expresiones, pero podría haber sido más y podría haber sido menos, dependiendo de mis requisitos.
Formulario 2:la expresión CASE buscada
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 @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
ELSE 'Expensive'
END
Resultado:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
Un 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
@stock_ticker
, y por lo tanto sabíamos que el WHEN
todas las expresiones se evaluaron contra el valor de @stock_ticker
.
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 WideWorldImporters;
SELECT
CityName AS [City],
LatestRecordedPopulation AS [Population],
Size =
CASE
WHEN LatestRecordedPopulation < 2000000 THEN 'Small City'
WHEN LatestRecordedPopulation >= 2000000 AND LatestRecordedPopulation < 3000000 THEN 'Big City'
ELSE 'Really Big City'
END
FROM Application.Cities
WHERE LatestRecordedPopulation > 1000000;
Resultado:
+--------------+--------------+-----------------+ | City | Population | Size | |--------------+--------------+-----------------| | Brooklyn | 2565635 | Big City | | Chicago | 2695598 | Big City | | Dallas | 1197816 | Small City | | Houston | 2099451 | Big City | | Los Angeles | 3792621 | Really Big City | | Manhattan | 1619090 | Small City | | New York | 8175133 | Really Big City | | Philadelphia | 1526006 | Small City | | Phoenix | 1445632 | Small City | | Queens | 2272771 | Big City | | San Antonio | 1327407 | Small City | | San Diego | 1307402 | Small City | | The Bronx | 1408473 | Small City | +--------------+--------------+-----------------+
Este ejemplo utiliza un CASE
buscado expresión para evaluar los resultados de LatestRecordedPopulation
columna de Application.Cities
mesa.
Tipos de datos
En SQL Server, el tipo de datos de la expresión de entrada y el WHEN
las expresiones deben ser iguales o deben ser una conversión implícita.
Esto es lo que sucede si no lo son:
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 1 THEN 'Apple'
WHEN 2 THEN 'Facebook'
WHEN 3 THEN 'Mastercard'
WHEN 4 THEN 'Visa'
ELSE 'Not in the portfolio'
END
Resultado:
Msg 245, Level 16, State 1, Line 3 Conversion failed when converting the varchar value 'V' to data type int.
Orden de Evaluación
El T-SQL CASE
expresión evalúa sus condiciones secuencialmente y se detiene con la primera condición cuya condición se cumple.
Para demostrar esto, usemos múltiples WHEN
expresiones que comparten el mismo valor:
DECLARE @stock_ticker varchar(4) = 'V';
SELECT Company =
CASE @stock_ticker
WHEN 'V' THEN 'Visa 1'
WHEN 'V' THEN 'Visa 2'
WHEN 'V' THEN 'Visa 3'
ELSE 'Not in the portfolio'
END
Resultado:
+-----------+ | Company | |-----------| | Visa 1 | +-----------+
En este caso, se detuvo en el primer WHEN
expresión.
Puede haber un escenario ocasional en el que una expresión se evalúe antes que un CASE
expresión recibe los resultados de la expresión como su entrada. En tales escenarios, podría terminar con un error. Esto podría suceder si incluye una expresión agregada como WHEN
expresión.
Por este motivo, Microsoft aconseja que:
Solo debe depender del orden de evaluación de las condiciones CUANDO para las expresiones escalares (incluidas las subconsultas no correlacionadas que devuelven escalares), no para las expresiones agregadas.
ELSE es opcional
El ELSE
argumento es opcional. Por lo tanto, podríamos reescribir nuestro ejemplo de "asequibilidad" de la siguiente manera:
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 THEN 'Expensive'
END
Resultado:
+-----------------+ | Affordability | |-----------------| | Expensive | +-----------------+
Aunque tenga en cuenta que podría terminar con NULL
si omite el ELSE
argumento.
El siguiente ejemplo da como resultado NULL
:
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
END
Resultado:
+-----------------+ | Affordability | |-----------------| | NULL | +-----------------+
En tales casos, siempre podríamos agregar un ELSE
argumento, por si acaso (¡perdón por el juego de palabras!):
DECLARE @price int = 1500;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
WHEN @price >= 500 AND @price < 1000 THEN 'Expensive'
ELSE 'Unknown'
END
Resultado:
+-----------------+ | Affordability | |-----------------| | Unknown | +-----------------+
Es cierto que este ejemplo es probablemente un poco artificial. Después de todo, no hay necesidad de limitar "caro". Si algo es caro por menos de $1000, también es caro si cuesta más de $1000.
Pero el punto es que puedes usar ELSE
para detectar cualquier cosa que no esté cubierta por WHEN
expresión/es.
Expresiones CASE anidadas
Puede anidar CASE
expresiones si es necesario.
DECLARE @price int, @on_sale bit;
SET @price = 1500;
SET @on_sale = 1;
SELECT Affordability =
CASE
WHEN @price < 100 THEN 'Cheap'
WHEN @price >= 100 THEN
CASE @on_sale
WHEN 0 THEN 'Expensive (but it''s not currently on sale)'
WHEN 1 THEN 'Expensive (and it''s already on sale!)'
END
END
Resultado:
+---------------------------------------+ | Affordability | |---------------------------------------| | Expensive (and it's already on sale!) | +---------------------------------------+
Sin embargo, es importante tener en cuenta que solo se permiten 10 niveles de anidamiento para CASE
expresiones en SQL Server. Si intenta anidar más de 10 niveles, obtendrá un error.
CASO en una Cláusula ORDER BY
Como se mencionó, el T-SQL 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 MusicGenres
ORDER BY Genre ASC;
Resultado:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Other | | Pop | | Rap | | Rock | +---------+
Aquí, ordenamos los resultados por Genre
columna, en orden ascendente.
Esto está bien excepto por una cosa. El género llamado Otro . ¿No sería bueno si pudiéramos mover Otro 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 MusicGenres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Resultado:
+---------+ | Genre | |---------| | Blues | | Country | | Hip Hop | | Jazz | | Metal | | Pop | | Rap | | Rock | | Other | +---------+
CASO en una instrucción UPDATE
Aquí hay un ejemplo del uso de un CASE
expresión en un UPDATE
declaración.
Supongamos que tenemos la siguiente tabla:
+---------+-----------+-----------+----------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+----------| | 1 | Fetch | 1 | NULL | | 2 | Fluffy | 0 | NULL | | 3 | Wag | 0 | NULL | | 1001 | Brian | 1 | NULL | | 1002 | Rambo | 0 | NULL | | 1003 | BamBam | 1 | NULL | +---------+-----------+-----------+----------+
Recientemente hemos añadido la Dinner
columna, y sigue siendo NULL
, esperando que se inserten valores.
Pero los valores a insertar dependerán del valor del GoodDog
columna.
Podríamos usar un CASE
expresión en tal escenario.
UPDATE Dogs
SET Dinner =
CASE GoodDog
WHEN 1 THEN 'Sunday Roast'
ELSE 'Airline food'
END
SELECT * FROM Dogs;
Resultado:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
CASO en una instrucción INSERT
Podemos tomar la tabla del ejemplo anterior e insertar un nuevo valor.
Y podemos volver a aprovechar el CASE
expresión para insertar el valor apropiado en Dinner
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
);
SELECT * FROM Dogs;
Resultado:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1 | Fetch | 1 | Sunday Roast | | 2 | Fluffy | 0 | Airline food | | 3 | Wag | 0 | Airline food | | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Esta vez el CASE
expresión estaba evaluando el valor de una variable que acabábamos de establecer, luego insertaba el valor apropiado en el Dinner
columna.
¿Es una instrucción CASE o una expresión CASE?
En SQL, muchas cosas se denominan "declaraciones" cuando, de hecho, son otra cosa. Esto también parece ser cierto para T-SQL “CASE
declaración”.
Aunque a menudo se le conoce como el CASE
declaración, es más exacto llamarlo CASE
expresión . Así es también como se refiere la documentación de Microsoft.
En SQL Server, en lugar de ser una declaración en sí misma, CASE
se puede usar en cualquier declaración o cláusula que permita una expresión válida. Una expresión es una combinación de símbolos y operadores que se evalúan para obtener un único valor de datos.
Sin embargo, algunos DBMS distinguen entre CASE
declaración, y el CASE
expresión, y tienen una sintaxis ligeramente diferente para cada uno. MySQL distingue entre el CASE
declaración y el CASE
operador, que es esencialmente el mismo que el CASE
expresión.