Trong SQL, CASE
câu lệnh đánh giá danh sách các điều kiện và trả về một trong nhiều biểu thức kết quả có thể có.
Theo một số cách, SQL CASE
tương tự như câu lệnh IF...ELSE
trong đó nó cho phép chúng tôi kiểm tra một điều kiện nhất định và trả về một kết quả khác tùy thuộc vào kết quả.
Có phải là CASE
không Tuyên bố hoặc CASE
Biểu cảm?
Trong SQL, đôi khi mọi thứ được gọi là một “câu lệnh” trong khi thực tế, chúng là một thứ gì đó khác. SQL “CASE
statement ”là một trường hợp điển hình (xin lỗi về cách chơi chữ!).
CASE
trong tiêu chuẩn SQL (ISO / IEC 9075) được gọi là câu lệnh CASE
biểu thức . Mục đích của nó là “chỉ định một giá trị có điều kiện”.
Tuy nhiên, một số DBMS phân biệt giữa CASE
câu lệnh và CASE
và có một cú pháp hơi khác nhau cho mỗi. Ví dụ:cả MySQL và MariaDB đều cung cấp CASE
câu lệnh và CASE
toán tử như hai tính năng riêng biệt, mỗi tính năng có cú pháp hơi khác nhau.
CASE
Định dạng
Trong SQL, có hai định dạng CASE
biểu thức:
-
CASE
đơn giản biểu hiện -
CASE
đã tìm kiếm biểu hiện
Dưới đây là các ví dụ về từng loại.
CASE
Đơn giản Biểu thức
CASE
đơn giản biểu thức so sánh một biểu thức với một tập hợp các biểu thức đơn giản để xác định kết quả.
Ví dụ:
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;
Kết quả:
Grass
Ví dụ này được thực hiện trong MySQL, nhưng CASE
thực tế biểu thức sẽ hoạt động trên hầu hết các RDBMS chính.
Trong ví dụ này, CASE
của tôi biểu thức là một phần của SELECT
tuyên bố. Nó kiểm tra ba điều kiện và có ELSE
để phục vụ cho bất kỳ thứ gì không nằm trong ba điều kiện.
Trong trường hợp này, động vật Cow
khớp với WHEN
thứ ba và biểu thức được cung cấp bởi THEN
của nó được trả lại.
Để rõ ràng, CASE
thực tế biểu thức là phần này:
CASE @animal
WHEN 'Bird' THEN 'Seed'
WHEN 'Dog' THEN 'Beef'
WHEN 'Cow' THEN 'Grass'
ELSE 'Leftovers'
END
Cái gì CASE
hiện là kiểm tra giá trị của mỗi WHEN
biểu thức so với biểu thức đầu vào. Trong ví dụ này, @animal
biến là biểu thức đầu vào. Do đó, nó đang kiểm tra giá trị của mỗi WHEN
biểu thức chống lại @animal
biến.
Khi / nếu nó tìm thấy một kết quả phù hợp, nó sẽ trả về biểu thức được cung cấp bởi THEN
tương ứng .
Ví dụ của tôi sử dụng ba WHEN
nhưng tôi có thể sử dụng nhiều hơn và tôi có thể sử dụng ít hơn, tùy thuộc vào yêu cầu.
CASE
được tìm kiếm Biểu thức
CASE
đã tìm kiếm biểu thức đánh giá một tập hợp các biểu thức Boolean để xác định kết quả.
Đây là ví dụ về CASE
được tìm kiếm biểu thức.
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;
Kết quả:
Well done!
CASE
đã tìm kiếm biểu thức không có biểu thức đầu vào như CASE
đơn giản biểu thức.
Bạn sẽ nhớ lại điều đó trong CASE
đơn giản của chúng tôi biểu thức, nó bắt đầu bằng CASE
@animal
và do đó chúng tôi biết rằng WHEN
tất cả các biểu thức đều được đánh giá dựa trên giá trị của @animal
.
Với CASE
đã tìm kiếm , chúng tôi không cung cấp một biểu thức đầu vào ở đầu như vậy. Thay vào đó, mỗi WHEN
biểu thức bao gồm một biểu thức Boolean được đánh giá dựa vào đó.
Một ví dụ về cơ sở dữ liệu
Dưới đây là một ví dụ minh họa cách CASE
biểu thức có thể được sử dụng trong một truy vấn cơ sở dữ liệu.
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;
Kết quả:
+---------------+------------+------------+ | 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 | +---------------+------------+------------+
Ví dụ này sử dụng CASE
được tìm kiếm biểu thức để đánh giá kết quả từ Population
cột của City
bàn.
ELSE
là Tùy chọn
ELSE
đối số là tùy chọn. Nếu chúng ta bỏ qua ELSE
và không có điều kiện nào được kích hoạt, kết quả là NULL
.
Đây là những gì sẽ xảy ra khi chúng tôi bỏ qua ELSE
mệnh đề từ ví dụ trước:
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;
Kết quả:
+---------------+------------+-----------+ | 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
trong một UPDATE
Tuyên bố
Hãy thêm một cột vào City
bảng từ ví dụ trước:
ALTER TABLE City
ADD COLUMN Size VARCHAR(30) AFTER Population;
SELECT * FROM City
LIMIT 10;
Bây giờ nó trông như thế nào:
+----+----------------+-------------+---------------+------------+------+ | 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 | +----+----------------+-------------+---------------+------------+------+
Chúng tôi chưa chèn bất kỳ dữ liệu nào vào Size
mới , vì vậy nó trả về NULL
trong mọi hàng.
Bây giờ chúng ta có thể sử dụng CASE
biểu thức để cập nhật Size
có giá trị phụ thuộc vào giá trị trong Population
cột:
UPDATE City
SET Size =
CASE
WHEN Population > 2000000 THEN 'Huge City'
WHEN Population >= 1000000 AND Population < 2000000 THEN 'Big City'
ELSE 'Small City'
END;
Bây giờ, hãy chọn dữ liệu từ bảng:
SELECT * FROM City
WHERE CountryCode = 'USA'
ORDER BY Population DESC
LIMIT 20;
Kết quả:
+------+---------------+-------------+---------------+------------+------------+ | 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
trong một INSERT
Tuyên bố
Giả sử chúng ta có bảng sau trong cơ sở dữ liệu SQL Server:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | +---------+-----------+-----------+--------------+
Hãy chèn một hàng mới vào bảng đó. Nhưng hãy sử dụng CASE
biểu thức để chèn giá trị thích hợp vào Dinner
, tùy thuộc vào giá trị trong GoodDog
cột:
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
);
Đây, CASE
biểu thức đã đánh giá giá trị của một biến mà chúng tôi vừa đặt, sau đó chèn giá trị thích hợp vào Dinner
cột.
Bây giờ chúng ta hãy kiểm tra lại bảng:
SELECT * FROM Dogs;
Kết quả:
+---------+-----------+-----------+--------------+ | DogId | DogName | GoodDog | Dinner | |---------+-----------+-----------+--------------| | 1001 | Brian | 1 | Sunday Roast | | 1002 | Rambo | 0 | Airline food | | 1003 | BamBam | 1 | Sunday Roast | | 1004 | Lazy | 0 | Airline food | +---------+-----------+-----------+--------------+
Chúng ta có thể thấy rằng giá trị thích hợp nằm trong Dinner
cột.
CASE
trong một ORDER BY
Mệnh đề
CASE
biểu thức có thể được sử dụng trong bất kỳ câu lệnh hoặc mệnh đề nào cho phép một biểu thức hợp lệ. Do đó, bạn có thể sử dụng nó trong các câu lệnh như SELECT
, UPDATE
, DELETE
và SET
và trong các mệnh đề như IN
, WHERE
, ORDER BY
, GROUP BY
và HAVING
.
Sử dụng CASE
biểu thức trong ORDER BY
của một câu lệnh mệnh đề có thể hữu ích khi bạn muốn tạo một ngoại lệ đặc biệt cho các giá trị nhất định khi sắp xếp các kết quả của bạn.
Giả sử chúng ta chạy truy vấn sau đối với một bảng chứa các thể loại nhạc.
SELECT Genre
FROM Genres
ORDER BY Genre ASC;
Kết quả:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Other | | Pop | | Punk | | Rap | | Rock | +---------+
Ở đây, chúng tôi sắp xếp các kết quả theo Genre
cột, theo thứ tự tăng dần.
Điều này là tốt, ngoại trừ một điều. Thể loại có tên Other
. Thật tuyệt nếu chúng ta có thể di chuyển Other
xuống dưới cùng?
Chúng ta có thể đạt được điều này với CASE
bằng cách sử dụng truy vấn trên và sửa đổi nó như sau.
SELECT Genre
FROM Genres
ORDER BY
CASE Genre
WHEN 'Other' THEN 1
ELSE 0
END
ASC, Genre ASC;
Kết quả:
+---------+ | Genre | +---------+ | Blues | | Country | | Hip Hop | | Jazz | | Pop | | Punk | | Rap | | Rock | | Other | +---------+
COALESCE()
và NULLIF()
Chức năng
Tùy thuộc vào tình huống, chúng ta có thể sử dụng các hàm như COALESCE()
và NULLIF()
như một phím tắt, thay vì sử dụng CASE
biểu thức.
Hai hàm này là chuẩn SQL và chúng hoạt động như sau:
NULLIF (V1, V2)
Tương đương với:
CASE WHEN V1=V2 THEN NULL ELSE V1 END
Và:
COALESCE (V1, V2)
Tương đương với:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END
Ngoài ra:
COALESCE (V1, V2, ..., Vn)
Tương đương với:
CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2, ..., Vn) END