Vấn đề
Trong SQL, NULL <> 2 không trả về TRUE hay FALSE mà trả về UNKNOWN. Do đó hàng có NULL bị loại bỏ khỏi kết quả.
Giải pháp: Sử dụng IS NOT NULL / IS NULL
SELECT * FROM ten_bang WHERE ten_cot IS NOT NULL OR ten_cot <> gia_tri;
Ví dụ minh họa
1. Tạo bảng
mysql> CREATE TABLE IsNullDemo ( -> ProductId INT, -> ProductName VARCHAR(100), -> ProductBackOrder INT -> ); Query OK, 0 rows affected (0.54 sec)
2. Chèn dữ liệu (có NULL)
mysql> INSERT INTO IsNullDemo VALUES(100,'First-Product',NULL); Query OK, 1 row affected (0.14 sec) mysql> INSERT INTO IsNullDemo VALUES(101,'Second-Product',2); Query OK, 1 row affected (0.22 sec) mysql> INSERT INTO IsNullDemo VALUES(102,'Third-Product',NULL); Query OK, 1 row affected (0.20 sec) mysql> INSERT INTO IsNullDemo VALUES(103,'Fourth-Product',4); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO IsNullDemo VALUES(104,'Fifth-Product',10); Query OK, 1 row affected (0.17 sec) mysql> INSERT INTO IsNullDemo VALUES(105,'Sixth-Product',NULL); Query OK, 1 row affected (0.20 sec)
3. Dữ liệu gốc
mysql> SELECT * FROM IsNullDemo;
+-----------+----------------+------------------+ | ProductId | ProductName | ProductBackOrder | +-----------+----------------+------------------+ | 100 | First-Product | NULL | | 101 | Second-Product | 2 | | 102 | Third-Product | NULL | | 103 | Fourth-Product | 4 | | 104 | Fifth-Product | 10 | | 105 | Sixth-Product | NULL | +-----------+----------------+------------------+ 6 rows in set (0.00 sec)
2 trường hợp xử lý
Trường hợp 1: Loại bỏ NULL (chỉ lấy không NULL VÀ khác 2)
mysql> SELECT * FROM IsNullDemo -> WHERE ProductBackOrder IS NOT NULL AND ProductBackOrder <> 2;
+-----------+----------------+------------------+ | ProductId | ProductName | ProductBackOrder | +-----------+----------------+------------------+ | 103 | Fourth-Product | 4 | | 104 | Fifth-Product | 10 | +-----------+----------------+------------------+ 2 rows in set (0.03 sec)
Trường hợp 2: Giữ NULL (lấy NULL HOẶC khác 2)
mysql> SELECT * FROM IsNullDemo -> WHERE ProductBackOrder IS NULL OR ProductBackOrder <> 2;
+-----------+----------------+------------------+ | ProductId | ProductName | ProductBackOrder | +-----------+----------------+------------------+ | 100 | First-Product | NULL | | 102 | Third-Product | NULL | | 103 | Fourth-Product | 4 | | 104 | Fifth-Product | 10 | | 105 | Sixth-Product | NULL | +-----------+----------------+------------------+ 5 rows in set (0.00 sec)
Bảng chân trị logic 3 giá trị (Three-Valued Logic)
| Biểu thức | Giá trị cột = 2 | Giá trị cột = 4 | Giá trị cột = NULL |
|---|---|---|---|
| cot = 2 | TRUE | FALSE | UNKNOWN |
| cot <> 2 | FALSE | TRUE | UNKNOWN |
| cot IS NULL | FALSE | FALSE | TRUE |
| cot IS NOT NULL | TRUE | TRUE | FALSE |
| cot <> 2 OR cot IS NULL | FALSE | TRUE | TRUE |
Hàm hỗ trợ xử lý NULL
-- Thay NULL bằng giá trị mặc định SELECT COALESCE(ProductBackOrder, 0) FROM IsNullDemo; -- So sánh an toàn với NULL (MySQL) SELECT * FROM IsNullDemo WHERE ProductBackOrder <=> 2; -- NULL-safe equal -- IFNULL (chỉ 2 tham số) SELECT IFNULL(ProductBackOrder, -1) FROM IsNullDemo;
Khuyến nghị
- Luôn nhớ:
NULL <> valuelà UNKNOWN, không phải TRUE - Dùng
IS NULL / IS NOT NULLđể kiểm tra NULL - Dùng
COALESCE()hoặcIFNULL()để thay thế NULL trước khi so sánh - MySQL có toán tử
<=>(NULL-safe equal) cho so sánh bằng an toàn