Học bằng cách đọc theo thứ tự

WHERE đào sâu ① — AND, OR, NOT để dựng điều kiện ghép

Bài đầu tiên trong loạt đào sâu WHERE. Bao gồm bảng chân trị cho AND / OR / NOT, độ ưu tiên toán tử, và cách dùng dấu ngoặc để làm rõ thứ tự đánh giá — tất cả chạy trên tập dữ liệu staff nạp từ CSV.

Dữ liệu sẽ dùng — bảng staff

Bắt đầu từ bài này, chúng ta sẽ dành ba bài đào sâu hơn về các mẫu lọc WHERE. Bài đầu tiên là các toán tử logic để dựng điều kiện ghépAND (và) / OR (hoặc) / NOT (không) — cộng với độ ưu tiên toán tửdấu ngoặc xuất hiện khi bạn trộn chúng.

Tập dữ liệu chủ đề là bảng staff (10 hàng) nạp từ CSV, với các cột name / city / salary / birthday. Chúng ta sẽ dựng các điều kiện thực tế thường gặp như "Tokyo và lương cao," "Tokyo hoặc Osaka," và "không phải Kyoto" bằng từng toán tử.

Trước các bài tập, hãy xác nhận định nghĩa cộtmột mẫu dữ liệu của bảng staff.

① Chạy PRAGMA table_info(staff); để kiểm tra tên cột, kiểu, và khóa chính.

② Chạy SELECT * FROM staff LIMIT 5; để xem trước 5 hàng đầu.

SQL Editor

Chạy truy vấn để xem kết quả

AND, OR, NOT — dựng điều kiện với toán tử logic

Toán tử logic kết hợp nhiều điều kiện trong một WHERE duy nhất. Có ba toán tử.

- `AND`: TRUE chỉ khi cả hai điều kiện đều TRUE

- `OR`: TRUE khi ít nhất một trong các điều kiện là TRUE

- `NOT`: phủ định điều kiện theo sau (TRUE → FALSE / FALSE → TRUE)

Cú pháp chỉ là chèn từ khóa: WHERE cond1 AND cond2, WHERE cond1 OR cond2, WHERE NOT (cond). Bạn có thể nối AND / OR bao nhiêu lần tùy ý, và NOT đặt trước một điều kiện đơn.

Điều kiện AĐiều kiện BA AND BA OR B
TrueTrueTrueTrue
TrueFalseFalseTrue
FalseTrueFalseTrue
FalseFalseFalseFalse

Quy tắc cơ bản là: AND chỉ TRUE khi cả hai TRUE; OR là TRUE khi một trong hai TRUE. Hành vi khi NULL bị trộn vào một so sánh được trình bày trong hai bài nữa dưới dạng logic ba giá trị, nhưng trong bài này chúng ta ở thế giới 2 giá trị (TRUE / FALSE) và chỉ học cách ghép điều kiện.

Độ ưu tiên toán tử logic
NOT(cao nhất)AND(giữa)OR(thấp nhất)tiếp theotiếp theo
NOT ràng buộc chặt nhất, sau đó AND, rồi OR — đó là thứ tự đánh giá. Khi bạn trộn chúng, dấu ngoặc cho phép bạn làm rõ thứ tự dự định để không phải nhớ độ ưu tiên trong đầu.
-- 1) AND: thỏa cả hai (Tokyo và lương cao)
SELECT name, city, salary FROM staff
WHERE city = 'Tokyo' AND salary >= 5000000;

-- 2) OR: thỏa một trong hai (Tokyo hoặc Osaka)
SELECT name, city FROM staff
WHERE city = 'Tokyo' OR city = 'Osaka';

-- 3) NOT: phủ định điều kiện (bất cứ đâu trừ Kyoto)
SELECT name, city FROM staff
WHERE NOT (city = 'Kyoto');

-- NOT cũng có thể viết với != hoặc <>
SELECT name, city FROM staff
WHERE city != 'Kyoto';

Hãy hình dung một đợt xét thưởng cần "staff ở Tokyo với lương ít nhất 5.000.000." (Khi bạn chạy đúng, phần giải thích sẽ hiện ra.)

① Từ staff, lấy các cột name, city, và salary.

② Lọc đến các hàng mà `city` là `'Tokyo'` VÀ `salary` ít nhất 5.000.000.

③ Xác nhận kết quả là 3 hàng (David Sato 6.800.000 / Grace Suzuki 5.500.000 / Jack Tanaka 5.900.000).

SQL Editor

Chạy truy vấn để xem kết quả

Hãy hình dung một thông báo cần gửi đến "staff ở khu vực Kanto (Tokyo) hoặc Kansai (Osaka)."

① Từ staff, lấy các cột namecity.

② Lọc đến các hàng mà `city` là `'Tokyo'` HOẶC `'Osaka'` (dùng OR).

③ Xác nhận kết quả là 6 hàng (Alice Tokyo / Bob Osaka / David Tokyo / Frank Osaka / Grace Tokyo / Jack Tokyo).

SQL Editor

Chạy truy vấn để xem kết quả

Độ ưu tiên toán tử — AND ràng buộc chặt hơn OR

Quy tắc duy nhất bạn nhất định phải biết khi trộn AND và OR là `AND` có độ ưu tiên cao hơn `OR`. Viết A OR B AND C được hiểu là `A OR (B AND C)` — không phải từ trái sang phải theo thứ tự viết.

Điều này thường tạo ra kết quả không khớp ý định của bạn, nên khi bạn trộn AND và OR, luôn làm rõ thứ tự đánh giá bằng dấu ngoặc. Dấu ngoặc không chỉ thay đổi ngữ nghĩa SQL — chúng còn báo hiệu ý định của bạn cho người đọc — nên kể cả khi nghĩa giống nhau dù có hay không có chúng, vẫn nên có thói quen đặt vào.

Cách dấu ngoặc thay đổi kết quả
Không có ngoặc(lệch khỏi ý định)Có ngoặc(khớp ý định)city = 'Tokyo'OR city = 'Osaka'AND salary >= 5000000(city = 'Tokyo' OR city = 'Osaka')AND salary >= 5000000Đọc thànhTokyo OR(Osaka AND lương cao)Đánh giá thành(Tokyo OR Osaka)AND lương caoKết quả: 6 hàng(bao gồm Alice Tokyo 4500k)Kết quả: 5 hàng(loại trừ Alice Tokyo 4500k)
Một truy vấn dự định là "lương cao ở Tokyo hoặc Osaka." Vị trí của dấu ngoặc thay đổi nghĩa — và kết quả.

`AND` được đánh giá trước `OR`

A OR B AND C được hiểu là `A OR (B AND C)`. AND ràng buộc chặt hơn OR, nên không đọc từ trái sang phải theo thứ tự viết.

Ví dụ: WHERE city = 'Tokyo' OR city = 'Osaka' AND salary >= 5000000 nghĩa là `city = 'Tokyo' OR (city = 'Osaka' AND salary >= 5000000)`, nên toàn bộ staff Tokyo được giữ bất kể lương (Alice Tokyo 4.500.000 được bao gồm). Nếu bạn muốn nói "lương cao trong số Tokyo hoặc Osaka," luôn viết (city = 'Tokyo' OR city = 'Osaka') AND salary >= 5000000làm rõ thứ tự đánh giá bằng dấu ngoặc.

Hãy hình dung nhu cầu "staff ở Tokyo hoặc Osaka với lương ít nhất 5.000.000." Trong một console duy nhất, so sánh kết quả có dấu ngoặc và không có dấu ngoặc để xem nó thay đổi thế nào.

① Từ staff, lấy các cột name, city, và salary.

② Trước tiên, viết dạng có dấu ngoặc, đúng ý định ((city = 'Tokyo' OR city = 'Osaka') AND salary >= 5000000).

③ Sau đó cố ý bỏ dấu ngoặc (city = 'Tokyo' OR city = 'Osaka' AND salary >= 5000000).

④ Xác nhận cái đầu trả về 5 hàng và cái thứ hai trả về 6 hàng (Alice Tokyo 4.500.000 được thêm vào) — kết quả thay đổi.

SQL Editor

Chạy truy vấn để xem kết quả

Hãy hình dung nhu cầu "dựng danh sách tất cả staff trừ những người ở Kyoto."

① Từ staff, lấy các cột namecity.

② Lọc đến các hàng mà `city` không phải `'Kyoto'` (dùng NOT (điều kiện)).

③ Xác nhận kết quả là 8 hàng (Carol và Iris bị loại trừ).

SQL Editor

Chạy truy vấn để xem kết quả
QUIZ

Kiểm tra kiến thức

Hãy trả lời từng câu hỏi một.

Câu 1Điều kiện WHERE WHERE city = 'Tokyo' OR city = 'Osaka' AND salary >= 5000000 được hiểu như thế nào?

Câu 2Dạng nào trả về cùng kết quả với WHERE NOT (city = 'Tokyo')?

Câu 3Cách đặt dấu ngoặc nào tương đương với WHERE A AND B OR C?