Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Expression SQL Server CASE

Dans SQL Server, le T-SQL CASE expression est une expression scalaire qui renvoie une valeur basée sur une logique conditionnelle. Il évalue une liste de conditions et renvoie une valeur, basée sur le résultat de ces conditions.

À certains égards, le SQL Server CASE l'expression est similaire à IF...ELSE . Cependant, CASE vous permet de vérifier plusieurs conditions, alors que IF...ELSE n'a pas.

De plus, dans SQL Server, IF...ELSE est un mot-clé du langage de contrôle de flux, alors que CASE n'est pas. Le CASE L'expression ne peut pas être utilisée pour contrôler le flux d'exécution des instructions T-SQL, des blocs d'instructions, des fonctions définies par l'utilisateur et des procédures stockées.

Les 2 formes d'expression CASE

Il existe deux formes de CASE expression dans SQL Server :

  • Simple CASE expression
  • Recherché CASE expression

Ceux-ci sont expliqués avec des exemples ci-dessous.

Formulaire 1 - L'expression CASE simple

Le simple CASE expression compare une expression à un ensemble d'expressions simples pour déterminer le résultat.

Voici un exemple de base pour montrer comment un CASE l'expression fonctionne dans 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 

Résultat :

+-----------+| Entreprise ||-----------|| Visa |+-----------+

Dans cet exemple, mon CASE l'expression fait partie d'un SELECT déclaration. Il vérifie trois conditions et a un ELSE pour répondre à tout ce qui n'est pas couvert dans les trois conditions.

Dans ce cas, le symbole boursier V correspond au troisième WHEN expression, et l'expression fournie par THEN est renvoyé.

Pour être clair, le véritable CASE expression est cette partie :

    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 

Quel CASE fait, il vérifie la valeur de chaque WHEN expression par rapport à l'expression d'entrée. Dans mon exemple, le @stock_ticker variable est l'expression d'entrée. Par conséquent, il vérifie la valeur de chaque WHEN expression contre le @stock_ticker variables.

Quand/s'il trouve une correspondance, il renvoie l'expression fournie par THEN .

Mon exemple utilise trois WHEN expressions, mais cela aurait pu être plus et cela aurait pu être moins, selon mes besoins.

Formulaire 2 - L'expression CASE recherchée

Le CASE recherché expression évalue un ensemble d'expressions booléennes pour déterminer le résultat.

Voici un exemple de CASE recherché expression.

DECLARE @price int = 1500;

SELECT Affordability =  
    CASE   
        WHEN @price < 100 THEN 'Cheap'
        WHEN @price >= 100 AND @price < 500 THEN 'Affordable'
        ELSE 'Expensive'  
    END 

Résultat :

+-----------------+| Abordabilité ||-----------------|| Cher |+-----------------+

Un CASE recherché expression n'a pas d'expression d'entrée comme le simple CASE expression.

Vous vous souviendrez que dans notre simple CASE expression, il a commencé par CASE @stock_ticker , et donc nous savions que le WHEN les expressions étaient toutes évaluées par rapport à la valeur de @stock_ticker .

Avec le CASE recherché expression, nous ne fournissons pas une expression d'entrée au début comme ça. Au lieu de cela, chaque WHEN expression inclut une expression booléenne pour laquelle elle doit être évaluée.

Un exemple de base de données

Voici un exemple qui montre comment le CASE expression peut être utilisée dans une requête de base de données.

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; 

Résultat :

+--------------+-------------+---------------- -+| Ville | Population | Taille ||--------------+-------------+----------------- || Brooklyn | 2565635 | Grande ville || Chicago | 2695598 | Grande ville || Dallas | 1197816 | Petite ville || Houston | 2099451 | Grande ville || Los Angeles | 3792621 | Vraiment grande ville || Manhattan | 1619090 | Petite ville || New-York | 8175133 | Vraiment grande ville || Philadelphie | 1526006 | Petite ville || Phénix | 1445632 | Petite ville || Reines | 2272771 | Grande ville || San-Antonio | 1327407 | Petite ville || San Diego | 1307402 | Petite ville || Le Bronx | 1408473 | Petite ville |+--------------+-------------+---------------- -+

Cet exemple utilise un CASE recherché expression pour évaluer les résultats de la LatestRecordedPopulation colonne de Application.Cities table.

Types de données

Dans SQL Server, le type de données de l'expression d'entrée et le WHEN les expressions doivent être identiques ou doivent être une conversion implicite.

Voici ce qui se passe si ce n'est pas le cas :

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 

Résultat :

Msg 245, Niveau 16, État 1, Ligne 3La conversion a échoué lors de la conversion de la valeur varchar 'V' en type de données int.

Ordre d'évaluation

Le CASE T-SQL expression évalue ses conditions séquentiellement et s'arrête à la première condition dont la condition est satisfaite.

Pour le démontrer, utilisons plusieurs WHEN expressions qui partagent la même valeur :

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 

Résultat :

+-----------+| Entreprise ||-----------|| Visa 1 |+-----------+

Dans ce cas, il s'est arrêté au premier WHEN expression.

Il peut arriver qu'une expression soit évaluée avant un CASE expression reçoit les résultats de l'expression en entrée. Dans de tels scénarios, vous pourriez vous retrouver avec une erreur. Cela peut se produire si vous incluez une expression agrégée comme WHEN expression.

Pour cette raison, Microsoft conseille que :

Vous ne devez dépendre que de l'ordre d'évaluation des conditions WHEN pour les expressions scalaires (y compris les sous-requêtes non corrélées qui renvoient des scalaires), pas pour les expressions agrégées.

SINON est facultatif

Le ELSE l'argument est facultatif. Par conséquent, nous pourrions réécrire notre exemple d'"abordabilité" comme suit :

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     

Résultat :

+-----------------+| Abordabilité ||-----------------|| Cher |+-----------------+

Cependant, gardez à l'esprit que vous pourriez vous retrouver avec NULL si vous omettez le ELSE argument.

L'exemple suivant donne 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     

Résultat :

+-----------------+| Abordabilité ||-----------------|| NULL |+-----------------+

Dans de tels cas, nous pourrions toujours ajouter un ELSE argument, juste au cas où (désolé pour le jeu de mots !):

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   

Résultat :

+-----------------+| Abordabilité ||-----------------|| Inconnu |+-----------------+

Certes, cet exemple est probablement un peu artificiel. Après tout, il n'est pas nécessaire de plafonner "coûteux". Si quelque chose coûte moins de 1 000 $, il est également cher s'il dépasse 1 000 $.

Mais le fait est que vous pouvez utiliser ELSE pour attraper tout ce qui n'est pas couvert par le WHEN expression/s.

Expressions CASE imbriquées

Vous pouvez imbriquer CASE expressions si nécessaire.

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 

Résultat :

+--------------------------------------------------+| Abordabilité ||--------------------------------------------------|| Cher (et c'est déjà soldé !) |+--------------------------------------------------- +

Cependant, il est important de noter que seuls 10 niveaux d'imbrication sont autorisés pour CASE expressions dans SQL Server. Si vous essayez d'imbriquer plus de 10 niveaux, vous obtiendrez une erreur.

CASE dans une clause ORDER BY

Comme mentionné, le T-SQL CASE expression peut être utilisée dans n'importe quelle instruction ou clause qui autorise une expression valide. Par conséquent, vous pouvez l'utiliser dans des instructions telles que SELECT , UPDATE , DELETE et SET , et dans des clauses telles que IN , WHERE , ORDER BY , GROUP BY , et HAVING .

Utiliser un CASE expression dans ORDER BY d'une instruction La clause peut être pratique lorsque vous souhaitez faire une exception spéciale pour certaines valeurs lors de la commande de vos résultats.

Supposons que nous lancions la requête suivante sur une table contenant des genres musicaux.

SELECT Genre 
FROM MusicGenres
ORDER BY Genre ASC; 

Résultat :

+---------+| Type ||---------|| Bleus || Pays || Hip Hop || Jazz || Métal || Autre || Pop || Rap || Rocher |+---------+

Ici, nous classons les résultats par Genre colonne, par ordre croissant.

C'est bien sauf pour une chose. Le genre appelé Autre . Ne serait-ce pas bien si nous pouvions déplacer Autre vers le bas ?

Nous pouvons y parvenir avec le CASE expression en prenant la requête ci-dessus et en la modifiant comme suit.

SELECT Genre
FROM MusicGenres
ORDER BY 
    CASE Genre
        WHEN 'Other' THEN 1
        ELSE 0
    END
    ASC, Genre ASC; 

Résultat :

+---------+| Type ||---------|| Bleus || Pays || Hip Hop || Jazz || Métal || Pop || Rap || Rocher || Autre |+---------+

CASE dans une instruction UPDATE

Voici un exemple d'utilisation d'un CASE expression dans un UPDATE déclaration.

Supposons que nous ayons le tableau suivant :

+---------+-----------+-----------+----------+| Identifiant du chien | NomChien | BonChien | Dîner ||---------+-----------+-----------+----------|| 1 | Récupérer | 1 | NUL || 2 | Moelleux | 0 | NUL || 3 | remuer | 0 | NUL || 1001 | Brian | 1 | NUL || 1002 | Rambo | 0 | NUL || 1003 | BamBam | 1 | NULL |+---------+-----------+-----------+----------+ 

Nous avons récemment ajouté le Dinner colonne, et c'est toujours NULL , en attente d'insertion de valeurs.

Mais les valeurs à insérer dépendront de la valeur du GoodDog colonne.

Nous pourrions utiliser un CASE expression dans un tel scénario.

UPDATE Dogs 
SET Dinner = 
    CASE GoodDog
        WHEN 1 THEN 'Sunday Roast'
        ELSE 'Airline food'
    END

SELECT * FROM Dogs; 

Résultat :

+---------+-----------+-----------+------------ --+| Identifiant du chien | NomChien | BonChien | Dîner ||---------+-----------+-----------+------------- -|| 1 | Récupérer | 1 | Rôti du dimanche || 2 | Moelleux | 0 | Nourriture aérienne || 3 | remuer | 0 | Nourriture aérienne || 1001 | Brian | 1 | Rôti du dimanche || 1002 | Rambo | 0 | Nourriture aérienne || 1003 | BamBam | 1 | Rôti du dimanche |+---------+-----------+-----------+------------ --+

CASE dans une instruction INSERT

Nous pouvons prendre le tableau de l'exemple ci-dessus et insérer une nouvelle valeur.

Et nous pouvons à nouveau profiter du CASE expression pour insérer la valeur appropriée dans le Dinner colonne.

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; 

Résultat :

+---------+-----------+-----------+------------ --+| Identifiant du chien | NomChien | BonChien | Dîner ||---------+-----------+-----------+------------- -|| 1 | Récupérer | 1 | Rôti du dimanche || 2 | Moelleux | 0 | Nourriture aérienne || 3 | remuer | 0 | Nourriture aérienne || 1001 | Brian | 1 | Rôti du dimanche || 1002 | Rambo | 0 | Nourriture aérienne || 1003 | BamBam | 1 | Rôti du dimanche || 1004 | Paresseux | 0 | Nourriture aérienne |+---------+-----------+-----------+------------ --+

Cette fois, le CASE expression évaluait la valeur d'une variable que nous venions de définir, puis insérait la valeur appropriée dans le Dinner colonne.

Est-ce une instruction CASE ou une expression CASE ?

En SQL, beaucoup de choses sont appelées "instructions" alors qu'en fait, c'est autre chose. Cela semble également être vrai pour le T-SQL "CASE déclaration".

Bien qu'il soit souvent appelé CASE déclaration, il est plus précis de l'appeler le CASE expression . C'est également ainsi que la documentation Microsoft y fait référence.

Dans SQL Server, plutôt que d'être une instruction elle-même, CASE peut être utilisé dans n'importe quelle instruction ou clause qui autorise une expression valide. Une expression est une combinaison de symboles et d'opérateurs qui sont évalués pour obtenir une seule valeur de données.

Cependant, certains SGBD font la distinction entre le CASE déclaration, et le CASE expression, et ont une syntaxe légèrement différente pour chacun. MySQL fait la distinction entre le CASE déclaration et le CASE opérateur, qui est essentiellement le même que le CASE expression.