Câu 1Trong các cấu trúc sau, đâu là cấu trúc biểu thức CASE đúng?
Hàm ⑤ — CASE để rẽ nhánh nhiều điều kiện
Bài thứ năm về hàm SQL. Hai dạng CASE (dạng đơn giản và dạng tìm kiếm), từ ba nhánh trở lên, kết hợp với hàm và điều kiện ghép, và ghép cùng ORDER BY — trên tập dữ liệu staff được tải từ CSV.
Dữ liệu dùng trong bài này — bảng staff
IIF ở bài trước chỉ có một điều kiện, nên chỉ rẽ nhánh hai chiều đúng/sai. Biểu thức CASE trong bài này xét ba điều kiện trở lên theo thứ tự và có thể trả về một giá trị khác cho mỗi điều kiện. Đây là cú pháp cơ bản để viết "if-elseif-else" bên trong SQL, và là cấu trúc rẽ nhánh phổ biến nhất trong công việc thực tế — phân loại báo cáo, gom nhóm theo vùng, xếp hạng điểm, v.v.
Đối tượng vẫn là bảng staff (10 hàng) như trước. Qua các bài thực hành dựng phân loại vùng trên cột city, phân loại khoảng lương trên salary, và phân loại thế hệ trên birthday, bạn sẽ lần lượt thử hai dạng CASE và ứng dụng của chúng cho điều kiện ghép.
CASE có hai cách viết
Biểu thức CASE có hai dạng — dạng đơn giản và dạng tìm kiếm — và cả hai đều cho ra cùng kết quả. Có hai quy tắc chung cho cả hai.
- `END` cuối cùng là bắt buộc — quên nó sẽ gây lỗi cú pháp.
- `ELSE` là tùy chọn — nếu bỏ qua, các hàng không khớp
WHENnào sẽ thành NULL. Để tránh NULL, hãy nêu rõ giá trị mặc định bằngELSE.
Dạng ① Dạng đơn giản — So sánh bằng trên một cột
Dạng đơn giản viết là CASE cột WHEN giá_trị1 THEN kết_quả1 WHEN giá_trị2 THEN kết_quả2 ... ELSE mặc_định END. Ngay sau CASE bạn đặt một cột để so sánh, và bên phải WHEN bạn viết một giá trị để kiểm tra cột có bằng hay không. Phép kiểm tra chỉ là so sánh bằng (`=`), và bên phải WHEN bạn chỉ viết được một giá trị duy nhất — không cho phép nhiều giá trị như WHEN ('Tokyo', 'Osaka'). Nó hợp với phép thay thế đơn giản cột = giá trị và viết ngắn hơn.
CASE city nhìn vào một cột và làm so sánh bằng với mỗi giá trị WHEN. Giá trị THEN của WHEN khớp sẽ được trả về; nếu không khớp cái nào, giá trị ELSE được dùng.-- Dạng đơn giản — thay city bằng tên vùng
SELECT name, city,
CASE city
WHEN 'Tokyo' THEN 'Kanto'
WHEN 'Yokohama' THEN 'Kanto'
WHEN 'Osaka' THEN 'Kansai'
WHEN 'Kyoto' THEN 'Kansai'
ELSE 'Other'
END AS region
FROM staff;
Dạng ② Dạng tìm kiếm — Viết điều kiện bất kỳ một cách tự do
Dạng tìm kiếm viết là CASE WHEN bt1 THEN kết_quả1 WHEN bt2 THEN kết_quả2 ... ELSE mặc_định END. Ngay sau CASE bạn không viết gì cả, và bên phải mỗi WHEN bạn đặt chính điều kiện đó. Toán tử so sánh như salary >= 6000000, LIKE như name LIKE '%Tanaka', IN, và điều kiện ghép AND / OR — bất cứ thứ gì viết được trong WHERE đều dùng được ở đây. WHEN được đánh giá từ trên xuống, và giá trị được quyết định bởi nhánh đầu tiên trở thành TRUE. Vì biểu cảm mạnh nên đây là dạng chủ yếu dùng trong thực tế.
WHEN được đánh giá từ trên xuống. Khi một điều kiện TRUE, giá trị THEN được chốt và không kiểm tra thêm. Nếu FALSE thì rơi xuống WHEN kế; nếu tất cả FALSE, giá trị ELSE được dùng.-- Dạng tìm kiếm — chia salary thành 2 khoảng
SELECT name, salary,
CASE
WHEN salary >= 5000000 THEN 'High'
ELSE 'Standard'
END AS pay_band
FROM staff;
Kết hợp với hàm và điều kiện ghép để rẽ nhánh phức tạp hơn
Một mệnh đề CASE WHEN có thể chứa các biểu thức kết hợp toán tử so sánh, LIKE, IN, AND / OR, và lời gọi hàm. Bạn có thể lấy năm sinh bằng strftime('%Y', birthday) đã học ở Hàm ① hàm ngày tháng để phân loại thế hệ; vì name theo thứ tự "tên họ", name LIKE '%Tanaka' (khớp hậu tố) phân loại những người có họ là Tanaka; và bạn có thể viết điều kiện kết hợp nhiều cột với AND.
Ví dụ bên dưới lấy năm sinh theo đơn vị 10 năm và gắn nhãn người sinh thập niên 1990 là 'Gen Z' và thập niên 1980 là 'Gen X-Y'. Vì strftime trả về chuỗi, các phép so sánh được thực hiện với hằng chuỗi ('1990' / '1999').
-- 1) Gắn nhãn năm sinh theo nhóm 5 năm
SELECT name, birthday,
CASE
WHEN strftime('%Y', birthday) BETWEEN '1985' AND '1989' THEN 'Late 1980s'
WHEN strftime('%Y', birthday) BETWEEN '1990' AND '1994' THEN 'Early 1990s'
ELSE 'Other'
END AS cohort
FROM staff;
-- 2) Điều kiện ghép: lương cao VÀ ở Tokyo
SELECT name, city, salary,
CASE
WHEN salary >= 6000000 AND city = 'Tokyo' THEN 'Tokyo senior'
WHEN salary >= 6000000 THEN 'Senior'
ELSE 'Other'
END AS tag
FROM staff;
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Đâu là mô tả đúng cho dạng đơn giản CASE city WHEN 'Tokyo' THEN 'TOK' WHEN 'Osaka' THEN 'OSA' ELSE city END?
Câu 3CASE WHEN salary >= 6000000 THEN 'Senior' WHEN salary >= 4500000 THEN 'Mid' ELSE 'Junior' END trả về gì cho một hàng có salary = 7,000,000?