Em SQL, o
CASE
A instrução avalia uma lista de condições e retorna uma das várias expressões de resultado possíveis. De certa forma, o SQL
CASE
declaração é um pouco semelhante ao IF...ELSE
declaração em que nos permite verificar uma determinada condição e retornar um resultado diferente dependendo do resultado. É um CASE
Declaração ou CASE
Expressão?
No SQL, às vezes as coisas são chamadas de “declarações” quando, na verdade, são outra coisa. O SQL “
CASE
declaração” é um caso em questão (desculpe o trocadilho!). O
CASE
A instrução é referida no padrão SQL (ISO/IEC 9075) como CASE
expressão . Seu objetivo é “especificar um valor condicional”. No entanto, alguns SGBDs distinguem entre o
CASE
instrução e o CASE
expressão e têm uma sintaxe ligeiramente diferente para cada um. Por exemplo, MySQL e MariaDB fornecem o CASE
instrução e o CASE
operador como dois recursos distintos, cada um com sintaxe ligeiramente diferente. CASE
Formatos
Em SQL, existem dois formatos de
CASE
expressão:- Simples
CASE
expressão - Pesquisou
CASE
expressão
Abaixo estão exemplos de cada um.
O simples CASE
Expressão
O simples
CASE
expressão compara uma expressão a um conjunto de expressões simples para determinar o resultado. Exemplo:
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 exemplo foi feito no MySQL, mas o
CASE
real expressão deve funcionar na maioria dos principais RDBMSs. Neste exemplo, meu
CASE
expressão é parte de um SELECT
demonstração. Ele verifica três condições e tem um ELSE
para atender a qualquer coisa que não esteja coberta nas três condições. Neste caso, o animal
Cow
corresponde ao terceiro WHEN
expressão e a expressão fornecida por seu THEN
é devolvido. Para ser claro, o
CASE
real expressão é esta parte: CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
O que
CASE
faz é verificar o valor de cada WHEN
expressão contra a expressão de entrada. Neste exemplo, o @animal
variável é a expressão de entrada. Portanto, está verificando o valor de cada WHEN
expressão contra o @animal
variável. Quando/se encontrar uma correspondência, retorna a expressão fornecida pelo
THEN
correspondente . Meu exemplo usa três
WHEN
expressões, mas eu poderia ter usado mais e poderia ter usado menos, dependendo dos requisitos. O CASE
pesquisado Expressão
O
CASE
pesquisado expression avalia um conjunto de expressões booleanas para determinar o resultado. Aqui está um exemplo de um
CASE
pesquisado expressão. 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!
O
CASE
pesquisado expressão não tem uma expressão de entrada como o simples CASE
expressão. Você se lembrará disso em nosso simples
CASE
expressão, começou com CASE
@animal
, e, portanto, sabíamos que o WHEN
expressões foram todas avaliadas em relação ao valor de @animal
. Com o
CASE
pesquisado expressão, não fornecemos uma expressão de entrada no início assim. Em vez disso, cada WHEN
expressão inclui uma expressão booleana para a qual será avaliada. Um exemplo de banco de dados
Aqui está um exemplo que demonstra como o
CASE
expressão pode ser usada em uma consulta de banco de dados. 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 exemplo usa um
CASE
pesquisado expressão para avaliar os resultados da Population
coluna da City
tabela. ELSE
é opcional
O
ELSE
argumento é opcional. Se omitirmos o ELSE
, e nenhuma das condições é acionada, o resultado é NULL
. Veja o que acontece quando omitimos o
ELSE
cláusula do exemplo 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
em um UPDATE
Declaração
Vamos adicionar uma coluna à
City
tabela do exemplo anterior:ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10;
Veja como está agora:
+----+----------------+-------------+---------------+------------+------+ | 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 | +----+----------------+-------------+---------------+------------+------+
Não inserimos nenhum dado no novo
Size
coluna, então ela retorna NULL
em cada fileira. Agora podemos usar um
CASE
expressão para atualizar o Size
coluna com um valor que depende do valor na Population
coluna:UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END;
Agora vamos selecionar os dados da tabela:
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
em um INSERT
Declaração
Suponha que temos a seguinte tabela em um banco de dados SQL Server:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
Vamos inserir uma nova linha nessa tabela. Mas vamos usar o
CASE
expressão para inserir o valor apropriado no Dinner
coluna, dependendo do valor no GoodDog
coluna: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
);
Aqui, o
CASE
expressão avaliou o valor de uma variável que acabamos de definir e, em seguida, inseriu o valor apropriado no Dinner
coluna. Agora vamos verificar a tabela novamente:
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 o valor apropriado está no
Dinner
coluna. CASE
em um ORDER BY
Cláusula
O
CASE
expressão pode ser usada em qualquer instrução ou cláusula que permita uma expressão válida. Portanto, você pode usá-lo em instruções como SELECT
, UPDATE
, DELETE
e SET
, e em cláusulas como IN
, WHERE
, ORDER BY
, GROUP BY
, e HAVING
. Usando um
CASE
expressão no ORDER BY
de uma instrução A cláusula pode ser útil quando você deseja fazer uma exceção especial para determinados valores ao ordenar seus resultados. Suponha que executemos a seguinte consulta em uma tabela contendo gêneros musicais.
SELECT Genre
FROM Genres
ORDER BY Genre ASC;
Resultado:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
Aqui, ordenamos os resultados pelo
Genre
coluna, em ordem crescente. Isso é bom, exceto por uma coisa. O gênero chamado
Other
. Não seria bom se pudéssemos mover Other
ao fundo? Podemos conseguir isso com o
CASE
expressão pegando a consulta acima e modificando-a da seguinte maneira. 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 | +---------+
O COALESCE()
e NULLIF()
Funções
Dependendo do cenário podemos usar funções como
COALESCE()
e NULLIF()
como um atalho, em vez de usar o CASE
expressão. Essas duas funções são padrão SQL e funcionam da seguinte forma:
NULLIF (V1, V2)
É equivalente a:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
E:
COALESCE (V1, V2)
É equivalente a:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
Também:
COALESCE (V1, V2, ..., Vn)
É equivalente a:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END