Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Instrução SQL CASE


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