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

Utilisation des expressions CASE dans SQL Server

Présentation

CASE Les expressions dans SQL Server sont utilisées pour la substitution des valeurs de colonne afin de présenter les ensembles de résultats d'une manière particulière ou de requêtes simples. Les cas d'utilisation de ces commandes sont variés.

Par exemple, il y a une colonne contenant le code du département, mais vous souhaitez afficher le nom du département plutôt que le code. Vous pouvez y parvenir en faisant un JOIN avec une autre table contenant les détails du département. Cependant, supposons que vous vouliez garder la requête relativement simple. Un autre cas d'utilisation serait de renvoyer des valeurs spécifiques pour l'ensemble de valeurs calculées. Les colonnes calculées ne conviendraient pas si les ensembles de conditions à spécifier ne sont pas les mêmes.

En règle générale, les expressions SQL Server CASE ont la forme indiquée dans la liste 1.

-- Listing 1: CASE Expression Syntax
-- Simple CASE Expression
SELECT 
  col1
, col2
, CASE col3
WHEN 'a' THEN 'xxx'
WHEN 'b' THEN 'yyy'
WHEN 'c' THEN 'zzz'
ELSE 'Invalid Value'
END AS col3_name
FROM table_name;

-- Searched CASE Expression
SELECT 
  col1
, col2
, CASE
WHEN col3 = 1 THEN 'xxx'
WHEN col3 BETWEEN 2 and 9 THEN 'yyy'
WHEN col3 > 10 THEN 'zzz'
ELSE 'Invalid Value'
END AS col3_name
FROM table_name;

Cas simple et cas recherché

Les deux scénarios décrits ci-dessus s'intègrent parfaitement dans les deux types d'expressions CASE disponibles dans SQL Server. Une expression CASE simple n'autorise que les vérifications d'égalité. Une expression Searched CASE autorise même les expressions booléennes.

Notez que les résultats d'une expression CASE tiennent dans une seule colonne. Notez également que nous spécifions le nom de la colonne juste après la clause CASE dans l'expression Simple CASE. Cependant, dans l'expression Searched CASE, nous devons spécifier le nom de la colonne pour chaque expression booléenne. Explorons quelques exemples.

Environnement du scénario

Dans notre exploration de l'expression CASE, nous utiliserons l'exemple de base de données bien connu WideWorldImporters. Là, nous utiliserons les Sales.CustomerTransactions tableau pour illustrer divers scénarios de l'application d'expression CASE. Comme c'est souvent le cas avec T-SQL, il est possible d'obtenir des résultats similaires en utilisant d'autres techniques, telles que les JOIN, mais nous nous concentrons sur une table pour montrer les capacités de l'expression CASE.

Notez qu'il faut comprendre les données manipulées pour utiliser les expressions CASE. Par exemple, nous devons savoir ce que chaque client code signifie représenter les données avec plus de sens pour l'utilisateur final. Dans nos cas, nous pouvons obtenir les informations d'autres tables.

Le listing 2 est une requête simple montrant à quoi ressemblent les données du tableau. La figure 1 nous montre une partie de sortie.

-- Listing 2: Data Set in Sales.CustomerTransactions
SELECT TOP (1000) [CustomerTransactionID]
      , [CustomerID]
      , [TransactionTypeID]
      , [InvoiceID]
      , [PaymentMethodID]
      , [TransactionDate]
      , [AmountExcludingTax]
      , [TaxAmount]
      , [TransactionAmount]
      , [OutstandingBalance]
      , [FinalizationDate]
      , [IsFinalized]
      , [LastEditedBy]
      , [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions] ;

Renvoyer les noms des clients en fonction de l'ID client

Dans cet exemple, nous souhaitons afficher le nom de chaque client en fonction du code client. Nous obtenons les noms des clients d'une autre table à l'aide d'une requête JOIN. Encore une fois, nous utilisons l'expression CASE pour démontrer ce que cette approche peut faire.

-- Listing 3a: Determine Names Using a Join
select distinct top 10 b.CustomerID, a.CustomerName
from Sales.Customers a,Sales.CustomerTransactions b
where a.CustomerID = b.CustomerID;
-- Listing 3b: Determine Names Using a Join (Alternative)
select distinct top 10 b.CustomerID, a.CustomerName
from Sales.Customers a
inner join Sales.CustomerTransactions b
on a.CustomerID = b.CustomerID;

Ayant ces informations, nous écrivons une simple requête CASE pour récupérer les données de Sales.CustomerTransactions seules (voir Listing 4). La figure 3 met en évidence les noms renvoyés par la requête.

Observez l'apparition de 'Clients inconnus' dans la sortie. Au sens propre, ces clients ne sont pas inconnus. Nous ne les avons pas car nous n'avons pas répondu à leur CustomerID dans notre expression CASE. Cela renforce la nécessité de comprendre les données lors de l'utilisation des expressions CASE.

-- Listing 4: Simple CASE Expression for Customer Name
SELECT TOP (20) 
CASE CustomerID 
	WHEN 1 THEN 'Tailspin Toys'
	WHEN 401 THEN 'Wingtip Toys'
	WHEN 801 THEN 'Eric Torres'
	WHEN 802 THEN 'Cosmina Vlad'
	WHEN 803 THEN 'Bala Dixit'
	WHEN 804 THEN 'Alekxandrs Reikstins'
	WHEN 805 THEN 'Ratan Podder'
	WHEN 806 THEN 'Shi Tu'
	WHEN 807 THEN 'Gunnar Lohmus'
	WHEN 808 THEN 'Jackson Kolios'
ELSE 'Unknown Customer'
END CustomerName
      , [InvoiceID]
      , [TransactionDate]
      , [TransactionAmount]
      , [OutstandingBalance]
      , [IsFinalized]
	  , [FinalizationDate]
      , [LastEditedBy]
      , [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions];

Renvoyer la classe de clients en fonction du montant de la transaction

Dans cet exemple, nous utilisons l'expression Searched CASE pour montrer lequel de nos clients a le plus de valeur en ce qui concerne la valeur de la transaction.

Nous classons les clients en trois groupes - Regular, Silver, Gold et Platinum, en fonction de la valeur de la transaction. Bien sûr, c'est simpliste. Dans un scénario réel, nous aurions besoin de faire la somme de leurs transactions sur une période donnée. Dans ce cas, nous n'utilisons qu'un sous-ensemble de données pour afficher les fonctionnalités de l'expression CASE.

-- Listing 5: Searched Case Expression for Customer Class 
SELECT TOP (20) 
CASE CustomerID 
	WHEN 1 THEN 'Tailspin Toys'
	WHEN 401 THEN 'Wingtip Toys'
	WHEN 801 THEN 'Eric Torres'
	WHEN 802 THEN 'Cosmina Vlad'
	WHEN 803 THEN 'Bala Dixit'
	WHEN 804 THEN 'Alekxandrs Reikstins'
	WHEN 805 THEN 'Ratan Podder'
	WHEN 806 THEN 'Shi Tu'
	WHEN 807 THEN 'Gunnar Lohmus'
	WHEN 808 THEN 'Jackson Kolios'
ELSE 'Unknown Customer'
END CustomerName
      	, [InvoiceID]
	, [TransactionDate] 
, CASE  
	WHEN [TransactionAmount] BETWEEN 100 AND 1000 THEN 'Silver Customer'
	WHEN [TransactionAmount] BETWEEN 1000 AND 3000 THEN 'Gold Customer'
	WHEN [TransactionAmount] >= 3000 THEN 'Platinum Customer'
	ELSE 'Regular Customer'
	END AS CustomerClass
, [OutstandingBalance]
      	, [IsFinalized]
	  , [FinalizationDate]
      	, [LastEditedBy]
      	, [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions];

Renvoyer le jour de la semaine à l'aide d'expressions CASE imbriquées

Nous procédons aux échantillons en ajoutant un échantillon nous indiquant quel jour de la semaine la date de transaction était (voir liste 6). Notez que nous aurions pu y parvenir en utilisant une forme beaucoup plus simple de la requête utilisant la fonction DATENAME plutôt que la fonction DATEPART.

-- Listing 6: Case Expression for Day of Week Using A Function  
SELECT TOP (20) 
CASE CustomerID 
	WHEN 1 THEN 'Tailspin Toys'
	WHEN 401 THEN 'Wingtip Toys'
	WHEN 801 THEN 'Eric Torres'
	WHEN 802 THEN 'Cosmina Vlad'
	WHEN 803 THEN 'Bala Dixit'
	WHEN 804 THEN 'Alekxandrs Reikstins'
	WHEN 805 THEN 'Ratan Podder'
	WHEN 806 THEN 'Shi Tu'
	WHEN 807 THEN 'Gunnar Lohmus'
	WHEN 808 THEN 'Jackson Kolios'
ELSE 'Unknown Customer'
END CustomerName
      , [InvoiceID]
, CASE  
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 1 THEN 'Sunday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 2 THEN 'Monday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 3 THEN 'Tuesday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 4 THEN 'Wednesday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 5 THEN 'Thursday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 6 THEN 'Friday'
	WHEN DATEPART(WEEKDAY,[TransactionDate]) = 7 THEN 'Saturday'
	END AS [Day of Week]
, CASE  
	WHEN [TransactionAmount] BETWEEN 100 AND 1000 THEN 'Silver Customer'
	WHEN [TransactionAmount] BETWEEN 1000 AND 3000 THEN 'Gold Customer'
	WHEN [TransactionAmount] >= 3000 THEN 'Platinum Customer'
	ELSE 'Regular Customer'
	END AS CustomerClass
	  , [OutstandingBalance]
      , [IsFinalized]
	  , [FinalizationDate]
      , [LastEditedBy]
      , [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions];

Étiquetage des transactions en fonction de la date

En utilisant le code des listes 7 et 8, nous pouvons étiqueter les transactions en fonction de la différence entre la date actuelle et la date de transaction. Cela s'applique également à la différence entre la date de transaction et une autre colonne. Par conséquent, nous pouvons introduire des colonnes autres que celles avec lesquelles nous travaillons comme entrée d'une expression booléenne.

  -- Listing 7: Case Expression for Transaction by Comparing Two “Columns”
SELECT TOP (20) 
CASE CustomerID 
	WHEN 1 THEN 'Tailspin Toys'
	WHEN 401 THEN 'Wingtip Toys'
	WHEN 801 THEN 'Eric Torres'
	WHEN 802 THEN 'Cosmina Vlad'
	WHEN 803 THEN 'Bala Dixit'
	WHEN 804 THEN 'Alekxandrs Reikstins'
	WHEN 805 THEN 'Ratan Podder'
	WHEN 806 THEN 'Shi Tu'
	WHEN 807 THEN 'Gunnar Lohmus'
	WHEN 808 THEN 'Jackson Kolios'
ELSE 'Unknown Customer'
END CustomerName
      , [InvoiceID]
, CASE  
	WHEN DATEDIFF(DAY,[TransactionDate],GETDATE()) < 30 THEN 'Current Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],GETDATE()) BETWEEN 30 AND 90 THEN 'Old Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],GETDATE()) BETWEEN 90 AND 365 THEN 'Stale Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],GETDATE()) >= 365 THEN 'Archived Transaction'
	END AS [Transaction Age]
, CASE  
	WHEN [TransactionAmount] BETWEEN 100 AND 1000 THEN 'Silver Customer'
	WHEN [TransactionAmount] BETWEEN 1000 AND 3000 THEN 'Gold Customer'
	WHEN [TransactionAmount] >= 3000 THEN 'Platinum Customer'
	ELSE 'Regular Customer'
	END AS CustomerClass
	  , [OutstandingBalance]
      , [IsFinalized]
	  , [FinalizationDate]
      , [LastEditedBy]
      , [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions];
-- Listing 8: Case Expression for Transaction by Comparing Two Columns  
SELECT TOP (20) 
CASE CustomerID 
	WHEN 1 THEN 'Tailspin Toys'
	WHEN 401 THEN 'Wingtip Toys'
	WHEN 801 THEN 'Eric Torres'
	WHEN 802 THEN 'Cosmina Vlad'
	WHEN 803 THEN 'Bala Dixit'
	WHEN 804 THEN 'Alekxandrs Reikstins'
	WHEN 805 THEN 'Ratan Podder'
	WHEN 806 THEN 'Shi Tu'
	WHEN 807 THEN 'Gunnar Lohmus'
	WHEN 808 THEN 'Jackson Kolios'
ELSE 'Unknown Customer'
END CustomerName
      , [InvoiceID]
, CASE  
	WHEN DATEDIFF(DAY,[TransactionDate],[FinalizationDate]) < 30 THEN 'Prompt Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],[FinalizationDate]) BETWEEN 30 AND 90 THEN 'Delayed Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],[FinalizationDate]) BETWEEN 90 AND 365 THEN 'Serverely Delayed Transaction'
	WHEN DATEDIFF(DAY,[TransactionDate],[FinalizationDate]) >= 365 THEN 'Orphaned Transaction'
	END AS [Transaction Response]
, CASE  
	WHEN [TransactionAmount] BETWEEN 100 AND 1000 THEN 'Silver Customer'
	WHEN [TransactionAmount] BETWEEN 1000 AND 3000 THEN 'Gold Customer'
	WHEN [TransactionAmount] >= 3000 THEN 'Platinum Customer'
	ELSE 'Regular Customer'
	END AS CustomerClass
, [OutstandingBalance]
      	, [IsFinalized]
, [FinalizationDate]
      	, [LastEditedBy]
      	, [LastEditedWhen]
  FROM [WideWorldImporters].[Sales].[CustomerTransactions];

Expressions CASE en dehors de la liste SELECT

Nous pouvons également utiliser des expressions CASE dans les instructions SET, les instructions UPDATE, les clauses WHERE, les clauses HAVING et les clauses ORDER BY.

La déclaration de mise à jour dans la liste 9 met à jour le OutstandingBalance colonne de lignes avec quatre ID client différents ayant des valeurs différentes. Cette instruction équivaut à écrire cinq instructions de mise à jour différentes pour chaque CASE, puis ELSE.

-- Listing 9: Update Statement with CASE Expression 
  UPDATE Sales.CustomerTransactions
  SET OutstandingBalance =
	(CASE 
		WHEN CustomerID = 832 THEN 100.00
		WHEN CustomerID = 803 THEN 150.00
		WHEN CustomerID = 905 THEN 200.00
		WHEN CustomerID = 976 THEN 70.00
		ELSE 50.00
	END
	);
	SELECT TOP 20 * FROM Sales.CustomerTransactions;

Conclusion

SQL et T-SQL vous permettent de remplacer les valeurs stockées dans une colonne par les valeurs souhaitées. Dans cet article, nous avons exploré les expressions CASE simples et recherchées avec des exemples.

Les expressions CASE peuvent être utilisées sur les clauses SELECT, SET, UPDATE, WHERE, HAVING et ORDER BY.

Références

CAS
Fonctions de date et d'heure