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

Câu lệnh SQL CASE:Nó là gì và những cách tốt nhất để sử dụng nó là gì?

Câu lệnh SQL CASE đánh giá và trả về kết quả dựa trên các giá trị, vị từ và điều kiện cụ thể theo logic đã xác định. Ví dụ:giả sử bạn có một bảng cử tri với các chi tiết sau:

  • ID người bỏ phiếu
  • Tên
  • DOB

Nếu bạn đang tìm kiếm logic về tính đủ điều kiện bỏ phiếu, điều này sẽ phụ thuộc vào các giá trị trong cột DOB.

Nếu độ tuổi của cử tri lớn hơn 18, họ đủ điều kiện bỏ phiếu.

Hãy xem một ví dụ khác. Nhiều lần, chúng tôi lưu trữ các giá trị cột theo bit 1 hoặc 0. Giả sử bạn lưu trữ các giá trị cho tính sẵn có của sản phẩm dưới dạng 1 hoặc 0. Ví dụ:

  • 1 =Sản phẩm có sẵn
  • 0 =Sản phẩm hết hàng

Nếu chúng ta nhìn từ góc độ cơ sở dữ liệu, bạn nên sử dụng các từ viết tắt hoặc bit ở bất cứ đâu có thể. Nó có lợi cho trình tối ưu hóa truy vấn SQL Server trong việc chuẩn bị kế hoạch thực thi được tối ưu hóa. Tuy nhiên, từ góc độ ứng dụng, người dùng cuối không yêu cầu những giá trị này. Khách hàng chỉ cần xem sản phẩm còn hàng hay không.

Trong hình ảnh dưới đây, chúng ta thấy cả cơ sở dữ liệu và phối cảnh ứng dụng.

Câu lệnh SQL CASE làm gì?

Câu lệnh CASE trong SQL Server đánh giá một biểu thức và trả về một giá trị dựa trên các điều kiện đã xác định. Do đó, trong ví dụ trước đó, các câu lệnh CASE hoạt động như được hiển thị bên dưới.

Ở cấp độ cao, cú pháp cho câu lệnh SQL CASE được hiển thị bên dưới. Ở đây, chúng tôi đã chỉ định nhiều điều kiện. SQL Server đánh giá các điều kiện một cách tuần tự. Khi một điều kiện đánh giá thành công, nó sẽ dừng việc đánh giá các điều kiện còn lại. Nếu không có điều kiện nào được thỏa mãn, chúng ta có thể sử dụng câu lệnh ELSE tùy chọn để trả về giá trị mặc định. Ví dụ, nếu chúng ta có một giá trị khác 0 và 1 trong cột tính khả dụng, bạn sẽ nhận được kết quả từ khối mã ELSE. Nó yêu cầu ít nhất một tập hợp các khối WHEN và THEN. Câu lệnh CASE phải kết thúc bằng khối END.

Hãy cùng khám phá câu lệnh SQL CASE bằng các ví dụ khác nhau.

Lưu ý:Trong bài viết này, chúng tôi sử dụng cơ sở dữ liệu mẫu của Microsoft, AdventureWorks. Bạn có thể tải xuống bản sao lưu của nó từ Microsoft Docs.

Câu lệnh SELECT với biểu thức CASE đơn giản

Trong loại câu lệnh CASE này, chúng tôi sử dụng biểu thức kiểm tra tính bình đẳng. Truy vấn sau đây triển khai một biểu thức CASE đơn giản.

  • Nếu giá trị trong [SalariedFlag] là 1, thì nó sẽ hiển thị Nhân viên đang hoạt động
  • Đối với tất cả các giá trị khác, nó hiển thị đầu ra là Nhân viên không hoạt động
SELECT TOP 5 Nationalidnumber ,
CASE salariedflag
WHEN 1 THEN 'Active Employee'
ELSE 'Inactive Employee'
END AS [Salaried Flag]
FROM [AdventureWorks2019].[HumanResources].[employee]

Chúng tôi có thể chỉ định nhiều điều kiện cho câu lệnh CASE.

SELECT TOP 5 Nationalidnumber ,
CASE salariedflag
WHEN 1 THEN 'Active Employee'
WHEN 0 THEN 'Inactive Employee'
ELSE 'Invalid Value'
END AS [Salaried Flag]
FROM [AdventureWorks2019].[HumanResources].[employee]

Chuẩn hóa dữ liệu bằng câu lệnh SQL CASE

Thông thường, chúng ta sử dụng các chữ viết tắt để lưu trữ các giá trị trong bảng SQL. Các chữ viết tắt tiêu chuẩn là giới tính, mã quốc gia, tình trạng hôn nhân, tên sản phẩm phổ biến, v.v.

Giả sử chúng ta chỉ định các chữ viết tắt để lưu trữ giới tính của nhân viên. Bây giờ, ứng dụng của chúng tôi sẽ hiển thị kết quả mà không có bất kỳ chữ viết tắt nào.

Các câu lệnh SQL CASE giúp chuẩn hóa kết quả đầu ra cho các tiêu chí đã xác định. Trong truy vấn dưới đây, chúng tôi sử dụng các điều kiện sau:

  • Nếu giá trị giới tính là M , hiển thị nó là Nam
  • Nếu giá trị giới tính là F , hiển thị nó là Nữ
  • Đối với bất kỳ giá trị nào khác, hiển thị Không hợp lệ Giá trị
SELECT DISTINCT CASE gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

Các câu lệnh CASE đã tìm kiếm

Trong câu lệnh CASE đã tìm kiếm, chúng tôi chỉ định một biểu thức CASE thay vì các giá trị trực tiếp. Khi giá trị biểu thức được đánh giá và thỏa mãn một điều kiện trong mệnh đề WHEN, giá trị tương ứng của nó sẽ được trả về.

Nhìn vào truy vấn SQL bên dưới. Ở đây, chúng tôi đã xác định các biểu thức trong mệnh đề WHEN cho [ListPrice]. Nó xác định rằng giá thành sản phẩm là 250 đô la và được đánh dấu là một mặt hàng Điện tử.

SELECT ProductNumber, Name, [Product category] = 
CASE 
WHEN ListPrice = 0 THEN 'Out of Stock items' 
WHEN ListPrice > 0 and ListPrice<=100 THEN 'Consumer goods' 
WHEN ListPrice >100 and ListPrice <= 500 THEN 'Electronics items' 
WHEN ListPrice >500 and ListPrice < 1500 THEN 'Luxury items' 
ELSE 'Extra items' 
END 
FROM Production.Product order by ListPrice desc

Đối với ví dụ về giới tính được đề cập trước đó, chúng ta có thể viết lại câu lệnh SQL CASE cho các từ viết tắt giới tính bằng cách sử dụng các câu lệnh trường hợp đã tìm kiếm.

SELECT DISTINCT CASE 
WHEN Gender='M' THEN 'Male'
WHEN Gender='F' THEN 'Female'
ELSE 'Invalid Value'
END AS Gender
FROM AdventureWorks2019.HumanResources.Employee

Sử dụng câu lệnh CASE với mệnh đề ORDER BY

Truy vấn SQL sử dụng mệnh đề ORDER BY để sắp xếp dữ liệu theo thứ tự tăng dần hoặc giảm dần. Bạn có thể sử dụng câu lệnh CASE kết hợp với mệnh đề ORDER BY. Giả sử từ bảng sản phẩm, chúng tôi truy xuất [Tên sản phẩm] và [Giá danh sách]. Chúng tôi muốn sắp xếp kết quả theo những cách sau:

  • Nếu giá niêm yết sản phẩm dưới 2.000, bạn muốn kết quả theo thứ tự sắp xếp mặc định, tức là tăng dần
  • Nếu giá niêm yết sản phẩm lớn hơn 2.000, điều khoản ORDER BY sắp xếp theo thứ tự giảm dần

Trong truy vấn này, chúng tôi sử dụng hai câu lệnh SQL CASE để triển khai logic.

SELECT Name,
ListPrice
FROM Production.Product
ORDER BY CASE
WHEN ListPrice<=2000 THEN ListPrice END 
,CASE WHEN ListPrice >2000 THEN ListPrice END DESC

Trong kết quả truy vấn bên dưới, bạn có thể xác minh các loại dữ liệu xuất hiện theo cả thứ tự giảm dần và tăng dần.

Trong một ví dụ khác, giả sử chúng ta muốn sắp xếp dữ liệu trong bảng nhân viên dựa trên điều kiện sau:

  • Đối với những nhân viên đang hoạt động (Cờ hiện tại =1), dữ liệu nên sắp xếp cột ngày tuyển dụng
  • Đối với những nhân viên không hoạt động, nó phải sắp xếp dữ liệu theo các giá trị trong cột ngày sinh
SELECT NationalIDNumber,JobTitle,Hiredate,BirthDate, currentflag
FROM AdventureWorks2019.HumanResources.Employee 
ORDER BY 
CASE CURRENTFLAG WHEN 1 THEN HireDate 
else Birthdate 
end

Trong đầu ra truy vấn, chúng tôi có thể xác minh thứ tự sắp xếp dữ liệu được xác định bởi mệnh đề ORDER BY và câu lệnh CASE.

Câu lệnh CASE trong SQL và các hàm tổng hợp

Các hàm tổng hợp trong SQL Server thực hiện các phép tính và trả về một giá trị duy nhất. Ví dụ về các hàm tổng hợp là MIN, MAX, COUNT, ABG và CHECKSUM.

Giả sử chúng ta muốn truy xuất số lượng nhân viên thuê cho mỗi năm từ 2007-2010. Nó sẽ hiển thị kết quả ở định dạng sau:

Với mục đích này, chúng tôi sử dụng hàm tổng hợp COUNT trong SQL Server.

  • Đầu tiên, hàm DATEPART của SQL lọc dữ liệu theo năm. Ví dụ:DATEPART (YY, Hiredate) =2007, lọc dữ liệu cho năm 2007.
  • Sau đó, chúng tôi sử dụng câu lệnh CASE để trả về 1 nếu năm là 2007.
  • Hàm tổng hợp đếm đếm các bản ghi và hiển thị kết quả.
  • Tương tự, truy vấn hoạt động trong những năm còn lại.
SELECT Count(CASE
WHEN Datepart(yy, hiredate) = 2007 THEN 1
ELSE NULL
END) AS [2007Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2008 THEN 1
ELSE NULL
END) AS [2008Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2009 THEN 1
ELSE NULL
END) AS [2009Hires],
Count(CASE
WHEN Datepart(yy, hiredate) = 2009 THEN 1
ELSE NULL
END) AS [2010Hires]
FROM AdventureWorks2019.HumanResources.Employee

Tương tự, giả sử chúng tôi muốn sử dụng hàm tổng hợp GROUP BY để nhóm các hàng có cùng danh mục sản phẩm. Chúng ta có thể chỉ định câu lệnh CASE trong SQL để sắp xếp dữ liệu từ tập kết quả đã nhóm.

SELECT [Product category] = CASE
WHEN listprice = 0 THEN 'Out of Stock items'
WHEN listprice > 0
AND listprice <= 100 THEN 'Consumer goods'
WHEN listprice > 100
AND listprice <= 500 THEN 'Electronics items'
WHEN listprice > 500
AND listprice < 1500 THEN 'Luxury items'
ELSE 'Extra items'
END,
Min(listprice) AS MinPrice,
Max(listprice) AS MaxPrice,
Count(listprice) AS Numberofproducts
FROM production.product
GROUP BY CASE
WHEN listprice = 0 THEN 'Out of Stock items'
WHEN listprice > 0
AND listprice <= 100 THEN 'Consumer goods'
WHEN listprice > 100
AND listprice <= 500 THEN 'Electronics items'
WHEN listprice > 500
AND listprice < 1500 THEN 'Luxury items'
ELSE 'Extra items'
END
ORDER BY numberofproducts DESC

Trong truy vấn trên, chúng tôi sử dụng hai câu lệnh SQL CASE.

  • Câu lệnh CASE đầu tiên phân loại dữ liệu dựa trên biểu thức được xác định trong giá niêm yết. Sử dụng câu lệnh CASE này, chúng tôi chia sản phẩm thành các loại sau:
    • Các mặt hàng hết hàng
    • Hàng tiêu dùng
    • Các mặt hàng điện tử
    • Các mặt hàng xa xỉ
  • Trong câu lệnh trường hợp thứ hai, chúng tôi sử dụng hàm tổng hợp GROUP BY để nhóm kết quả theo danh mục
  • Hơn nữa, chúng tôi sắp xếp các kết quả theo NumberOfProducts theo thứ tự giảm dần

Ngăn lỗi chia cho 0 bằng câu lệnh SQL CASE

Lỗi chia cho 0 xảy ra nếu giá trị mẫu số bằng 0. Nếu bạn thực hiện các phân số này trong SQL Server, nó sẽ cung cấp cho bạn lỗi chia cho 0 như được hiển thị bên dưới.

Đó là một thực tiễn tuyệt vời để viết các truy vấn của bạn theo cách để tránh những lỗi phổ biến này. Để tránh điều này, chúng tôi sử dụng logic phân số bên trong câu lệnh CASE.

DECLARE @Student1 INT
DECLARE @Student2 INT

SET @Student1=100
SET @Student2=0

select
CASE WHEN @Student2=0
THEN NULL
ELSE @Student1/@Student2 end as StudentMarksRatio

Chúng tôi đã bảo vệ truy vấn của mình khỏi lỗi chia cho 0. Bây giờ, với logic đã sửa đổi, nếu chúng ta nhận được số 0 ở mẫu số, bạn nhận được NULL trong đầu ra như hình dưới đây.

Lời nhắc hữu ích về câu lệnh SQL CASE

  • Các câu lệnh SQL CASE hỗ trợ tối đa 10 cấp độ lồng nhau
  • Bạn không thể kiểm soát luồng thực thi các câu lệnh, hàm hoặc thủ tục bằng cách sử dụng biểu thức CASE
  • Bạn phải luôn sử dụng khối ELSE để nếu bất kỳ điều kiện nào không được thỏa mãn, bạn sẽ nhận được giá trị mặc định
  • Bạn nên tránh sử dụng các điều kiện xung đột trong câu lệnh SQL CASE. Câu lệnh CASE hoạt động tuần tự và ngừng đánh giá với điều kiện thành công đầu tiên

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách thiết lập Thư cơ sở dữ liệu trong SQL Server (SSMS)

  2. Brent Ozar giải thích sự phân mảnh bên trong và bên ngoài của SQL Server

  3. Thêm tài khoản thư cơ sở dữ liệu vào cấu hình (T-SQL)

  4. Chuyển đổi truy vấn SQL Server sang MySQL

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