sql >> Base de Datos >  >> RDS >> Mysql

Sentencia SQL CASE

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