Khi làm việc với cơ sở dữ liệu, bạn có thể muốn chạy một phép toán if/then (nếu/thì) trong truy vấn. Ví dụ: duyệt danh sách nhân viên và thay đổi trạng thái thử việc nếu họ làm việc quá một năm. Hoặc duyệt bảng xếp hạng người chơi và đánh dấu "người chiến thắng" nếu họ đứng top 3.
Để thực hiện các phép toán này trong SQL, bạn phải dùng câu lệnh CASE. Câu lệnh SQL CASE cho phép chạy logic if/then, tương tự cách bạn dùng if/then trong Microsoft Excel.
Trong hướng dẫn này, chúng ta sẽ phân tích cơ bản của câu lệnh SQL CASE và cách sử dụng trong truy vấn. Chúng ta cũng sẽ thảo luận về việc dùng nhiều câu lệnh CASE và cách CASE kết hợp với hàm tổng hợp (aggregate functions).
Ôn tập truy vấn
Để lấy thông tin từ cơ sở dữ liệu, bạn cần viết truy vấn. Truy vấn gần như luôn bắt đầu bằng câu lệnh SELECT — chỉ định cột nào sẽ được trả về. Truy vấn cũng thường có mệnh đề FROM — chỉ định bảng sẽ được tìm kiếm.
Cú pháp truy vấn trong SQL:
SELECT ten_cot FROM ten_bang WHERE dieu_kien;
Ví dụ: lấy tên tất cả nhân viên trong bảng employees:
SELECT name FROM employees;
Kết quả:
| name |
|---|
| Luke Mike Hannah Geoff Alexis Emma Jonah Adam |
(8 hàng)
Nếu muốn lấy nhiều cột, phân tách tên cột bằng dấu phẩy. Để lấy mọi cột, dùng toán tử dấu hoa thị (*).
Ngoài ra, nếu muốn lọc bản ghi dựa trên điều kiện cụ thể, dùng mệnh đề WHERE. Ví dụ: tìm tên nhân viên tại chi nhánh Albany:
SELECT name FROM employees WHERE branch = 'Albany';
Kết quả:
| name |
|---|
| Emma Jonah |
(2 hàng)
Đây là các truy vấn đơn giản. Nhưng nếu muốn thực hiện phép toán if/then khi chạy truy vấn? Đó là lúc câu lệnh SQL CASE hữu ích.
SQL CASE
Câu lệnh CASE dùng trong SQL để định nghĩa logic if/then trong mã. Ví dụ: muốn tăng lương cho nhân viên làm việc từ 5 năm trở lên, có thể dùng CASE.
Cú pháp câu lệnh SQL CASE:
SELECT ten_cot1 CASE WHEN ten_cot2 = 'X' THEN 'Y' ELSE NULL END AS ten_cot3 FROM ten_bang;
Có nhiều thứ xảy ra trong truy vấn này, hãy dùng ví dụ minh họa. Giả sử muốn tăng $200 cho nhân viên có hơn 5 giải "nhân viên tháng":
SELECT name, CASE WHEN employee_month_awards > 5 THEN 200 ELSE NULL END AS pending_raise FROM employees;
Kết quả:
| name | pending_raise |
|---|---|
| Luke | |
| Mike | |
| Hannah | |
| Geoff | |
| Alexis | |
| Emma | 200 |
| Jonah | |
| Adam | 200 |
(8 hàng)
Giải thích: Câu lệnh CASE kiểm tra từng bản ghi và đánh giá xem điều kiện employee_month_awards > 5 có đúng không. Nếu đúng, giá trị 200 sẽ hiển thị trong cột pending_raise. Nếu sai, giá trị NULL được giữ lại.
Cuối cùng, truy vấn trả về danh sách tên nhân viên và mức tăng lương chờ duyệt.
Lưu ý: Câu lệnh SQL CASE không thêm cột mới vào bảng. Nó tạo một cột trong đầu ra của truy vấn SELECT để chúng ta thấy ai đủ điều kiện tăng lương.
Nếu muốn nhân viên không đủ điều kiện nhận $0 thay vì NULL, hãy thay NULL bằng 0 trong mệnh đề ELSE. Bạn cũng có thể dùng ORDER BY để sắp xếp kết quả theo ý muốn.
SQL CASE với nhiều điều kiện
Câu lệnh CASE có thể dùng nhiều lần trong cùng một truy vấn. Nếu muốn: nhân viên có ≥3 giải được tăng $50, ≥5 giải được tăng $200:
SELECT name,
CASE
WHEN employee_month_awards > 5 THEN 200
WHEN employee_month_awards > 3 THEN 50
ELSE 0
END AS pending_raise
FROM employees;
Kết quả:
| name | pending_raise |
|---|---|
| Luke | 50 |
| Mike | |
| Hannah | |
| Geoff | |
| Alexis | |
| Emma | 200 |
| Jonah | 50 |
| Adam | 200 |
(8 hàng)
Trong ví dụ này, các câu lệnh CASE được đánh giá theo thứ tự viết. Truy vấn trước kiểm tra >5 giải → gán 200. Sau đó kiểm tra >3 giải → gán 50. Cuối cùng, không đáp ứng tiêu chí nào → gán 0.
Tuy nhiên, mã này có thể hiệu quả hơn. Thay vì phụ thuộc vào thứ tự, hãy viết điều kiện không chồng chéo bằng AND:
SELECT name,
CASE
WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
WHEN employee_month_awards > 5 THEN 200
ELSE 0
END AS pending_raise
FROM employees;
Truy vấn này trả về kết quả giống hệt nhưng không phụ thuộc thứ tự CASE, giảm thiểu rủi ro lỗi do đặt sai thứ tự.
SQL CASE và hàm tổng hợp (Aggregate Functions)
Bạn cũng có thể dùng CASE với hàm tổng hợp. Hữu ích khi chỉ muốn đếm các hàng đáp ứng điều kiện nhất định. Ví dụ: đếm số nhân viên đủ điều kiện nhận thưởng $200.
Cú pháp:
SELECT ten_cot1 CASE WHEN ten_cot2 = 'X' THEN 'Y' ELSE NULL END AS ten_cot3, COUNT(1) AS count FROM ten_bang GROUP BY ten_cot3;
Ví dụ: đếm số nhân viên đủ điều kiện nhận thưởng $50 trở lên:
SELECT
CASE
WHEN employee_month_awards >= 3 AND employee_month_awards <= 5 THEN 50
WHEN employee_month_awards > 5 THEN 200
ELSE 0
END AS pending_raise,
COUNT(1) AS count
FROM employees
GROUP BY pending_raise;
Kết quả:
| pending_raise | count |
|---|---|
| 50 | 3 |
| 0 | 3 |
| 200 | 2 |
Truy vấn trả về danh sách các mức tăng lương chờ và số lượng nhân viên tương ứng: 3 nhân viên tăng $50, 3 nhân viên không tăng, 2 nhân viên tăng $200.
Kết luận
Trong hướng dẫn này, chúng ta đã phân tích cơ bản của câu lệnh SQL CASE và cách triển khai logic if/then trong truy vấn. Cũng thảo luận về CASE với nhiều điều kiện và kết hợp hàm tổng hợp.
Nhắc nhở: mọi biểu thức CASE đơn giản nên tuân thủ các quy tắc:
- Câu lệnh
CASEphải nằm trong mệnh đềSELECT. - Phải bao gồm các thành phần
WHEN,THENvàEND. - Có thể dùng nhiều câu lệnh
WHENvà mệnh đềELSEtùy chọn. - Các điều kiện như
ANDhoặcORcó thể dùng trong truy vấnCASEgiữaWHENvàTHEN.
Bây giờ bạn đã trang bị kiến thức để dùng câu lệnh CASE như một chuyên gia SQL!