Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Sử dụng biểu thức CASE trong SQL Server

Giới thiệu

Biểu thức CASE trong SQL Server được sử dụng để thay thế giá trị cột để trình bày các tập kết quả theo một kiểu cụ thể hoặc các truy vấn đơn giản. Các trường hợp sử dụng cho các lệnh như vậy rất khác nhau.

Ví dụ:có một cột chứa mã bộ phận, nhưng bạn muốn hiển thị tên bộ phận thay vì mã. Bạn có thể đạt được điều đó bằng cách thực hiện JOIN với một bảng khác có chứa thông tin chi tiết về bộ phận. Tuy nhiên, giả sử bạn muốn giữ cho truy vấn tương đối đơn giản. Một trường hợp sử dụng khác sẽ trả về các giá trị cụ thể cho bộ giá trị đã tính toán. Các cột được tính sẽ không phù hợp nếu tập hợp các điều kiện cần chỉ định không giống nhau.

Thông thường, Biểu thức SQL Server CASE có dạng được hiển thị trong Liệt kê 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;

Hộp đựng đơn giản và Hộp đựng đã tìm kiếm

Hai trường hợp được mô tả ở trên khá phù hợp với hai loại biểu thức CASE có sẵn trong SQL Server. Biểu thức CASE đơn giản chỉ cho phép kiểm tra bình đẳng. Biểu thức CASE đã tìm kiếm cho phép biểu thức Boolean chẵn.

Lưu ý rằng kết quả của một biểu thức CASE phù hợp với một cột duy nhất. Ngoài ra, hãy quan sát rằng chúng ta chỉ định tên cột ngay sau mệnh đề CASE trong biểu thức CASE đơn giản. Tuy nhiên, trong Biểu thức CASE đã Tìm kiếm, chúng ta phải chỉ định tên cột cho mỗi biểu thức Boolean. Hãy khám phá một số ví dụ.

Môi trường tình huống

Trong quá trình khám phá biểu thức CASE, chúng tôi sẽ sử dụng cơ sở dữ liệu mẫu WideWorldImporters nổi tiếng. Ở đó, chúng tôi sẽ sử dụng Sales.CustomerTransactions để trình bày các kịch bản khác nhau của ứng dụng biểu thức CASE. Như thường thấy với T-SQL, có thể nhận được các kết quả tương tự bằng cách sử dụng các kỹ thuật khác, chẳng hạn như JOIN, nhưng chúng tôi tập trung vào một bảng để hiển thị các khả năng của biểu thức CASE.

Lưu ý rằng người ta phải hiểu dữ liệu được xử lý để sử dụng biểu thức CASE. Ví dụ:chúng ta phải biết những gì từng khách hàng mã có nghĩa là đại diện cho dữ liệu có ý nghĩa hơn đối với người dùng cuối. Trong trường hợp của chúng tôi, chúng tôi có thể lấy thông tin từ các bảng khác.

Liệt kê 2 là một truy vấn đơn giản hiển thị dữ liệu trong bảng trông như thế nào. Hình 1 cho chúng ta thấy một phần đầu ra.

-- 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] ;

Tên khách hàng trả lại dựa trên ID khách hàng

Trong ví dụ này, chúng tôi muốn hiển thị tên của từng khách hàng dựa trên mã khách hàng. Chúng tôi lấy tên của khách hàng từ một bảng khác bằng cách sử dụng truy vấn JOIN. Một lần nữa, chúng tôi đang sử dụng Biểu thức CASE để chứng minh những gì phương pháp này có thể làm.

-- 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;

Có thông tin này, chúng tôi viết một truy vấn CASE đơn giản để truy xuất dữ liệu từ riêng Sales.CustomerTransactions (Xem Liệt kê 4). Hình 3 làm nổi bật các tên được trả về bởi truy vấn.

Quan sát sự xuất hiện của ‘Khách hàng không xác định’ trong đầu ra. Theo nghĩa thực tế, những khách hàng này không phải là không biết. Chúng tôi không có chúng vì chúng tôi không cung cấp cho CustomerID của họ trong biểu thức CASE của chúng tôi. Điều này nhấn mạnh sự cần thiết phải hiểu dữ liệu khi sử dụng Biểu thức 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];

Trả lại hạng khách hàng dựa trên số tiền giao dịch

Trong ví dụ này, chúng tôi sử dụng biểu thức CASE đã tìm kiếm để cho biết khách hàng nào của chúng tôi có giá trị hơn về giá trị giao dịch.

Chúng tôi phân loại khách hàng thành ba nhóm - Thông thường, Bạc, Vàng và Bạch kim, dựa trên giá trị giao dịch. Tất nhiên, điều này là đơn giản. Trong một tình huống thực tế, chúng tôi sẽ cần phải tính tổng các giao dịch của họ trong một khoảng thời gian nhất định. Trong trường hợp này, chúng tôi chỉ sử dụng một tập hợp con dữ liệu để hiển thị các khả năng của Biểu thức 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];

Kể lại ngày trong tuần bằng biểu thức CASE lồng nhau

Chúng tôi tiếp tục với các mẫu bằng cách thêm một mẫu cho chúng tôi biết Ngày giao dịch là ngày nào trong tuần (Xem Liệt kê 6). Lưu ý rằng chúng tôi có thể đạt được điều này bằng cách sử dụng một dạng truy vấn đơn giản hơn nhiều bằng cách sử dụng hàm DATENAME thay vì hàm 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];

Giao dịch gắn nhãn dựa trên ngày

Sử dụng mã trong Liệt kê 7 và 8, chúng tôi có thể gắn nhãn các giao dịch dựa trên sự khác biệt giữa ngày hiện tại và ngày giao dịch. Nó cũng áp dụng cho sự khác biệt giữa ngày giao dịch và một cột khác. Do đó, chúng tôi có thể giới thiệu các cột khác với những cột mà chúng tôi đang làm việc làm đầu vào cho biểu thức Boolean.

  -- 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];

Biểu thức CASE Bên ngoài Danh sách CHỌN

Chúng ta cũng có thể sử dụng biểu thức CASE trong câu lệnh SET, câu lệnh UPDATE, mệnh đề WHERE, mệnh đề HAVING và mệnh đề ORDER BY.

Tuyên bố Cập nhật trong Liệt kê 9 cập nhật Dư nợ vượt trội cột các hàng có bốn ID khách hàng khác nhau có các giá trị khác nhau. Câu lệnh này tương đương với việc viết năm câu lệnh cập nhật khác nhau cho mỗi CASE và sau đó là 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;

Kết luận

SQL và T-SQL cho phép bạn thay thế các giá trị được lưu trữ trong một cột bằng các giá trị mong muốn của bạn. Trong bài viết này, chúng tôi đã khám phá các biểu thức CASE đơn giản và được tìm kiếm với các ví dụ.

Biểu thức CASE có thể được sử dụng cho các mệnh đề SELECT, câu lệnh SET, câu lệnh UPDATE, WHERE, HAVING và ORDER BY.

Tài liệu tham khảo

TRƯỜNG HỢP
Chức năng ngày và giờ


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chuyển dữ liệu từ cơ sở dữ liệu này sang cơ sở dữ liệu khác

  2. Trả về tất cả các khóa ngoại tham chiếu đến một bảng đã cho trong SQL Server

  3. Phân tích cú pháp JSON trong TSQL

  4. Có thể nối các giá trị cột vào một chuỗi bằng CTE không?

  5. SQL động (chuyển tên bảng làm tham số)