ปัญหา: IN() ไม่จับคู่ NULL
ใน SQL, NULL IN (value1, value2) คืนค่า UNKNOWN (ไม่ใช่ TRUE) → ไม่ถูก SELECT
ตัวอย่าง: ตาราง demo60
CREATE TABLE demo60 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(20),
last_name VARCHAR(20)
);
INSERT INTO demo60 (first_name, last_name) VALUES
('John', 'Smith'), ('John', 'Doe'), (NULL, 'Brown'),
('David', 'Miller'), ('David', 'Smith'), ('Chris', 'Brown');
ข้อมูล
+----+------------+-----------+ | id | first_name | last_name | +----+------------+-----------+ | 1 | John | Smith | | 2 | John | Doe | | 3 | NULL | Brown | | 4 | David | Miller | | 5 | David | Smith | | 6 | Chris | Brown | +----+------------+-----------+
คำสั่ง: หา 'John' ใน first_name/last_name หรือ first_name IS NULL
SELECT id, first_name, last_name FROM demo60 WHERE 'John' IN (first_name, last_name) OR first_name IS NULL;
ผลลัพธ์ (id 1, 2, 3)
+----+------------+-----------+ | id | first_name | last_name | +----+------------+-----------+ | 1 | John | Smith | | 2 | John | Doe | | 3 | NULL | Brown | +----+------------+-----------+
คำอธิบาย
- แถว 1,2: 'John' IN (first_name, last_name) → TRUE
- แถว 3: first_name IS NULL → TRUE (แม้ 'John' IN (NULL, 'Brown') จะเป็น UNKNOWN)
- แถว 4,5,6: ทั้งสองเงื่อนไข FALSE
จุดสำคัญ: NULL ใน IN()
-- ผลลัพธ์ต่างกัน
SELECT 'John' IN ('John', 'Smith'); -- 1 (TRUE)
SELECT 'John' IN (NULL, 'Smith'); -- NULL (UNKNOWN)
SELECT NULL IN ('John', 'Smith'); -- NULL (UNKNOWN)
SELECT NULL IN (NULL, 'Smith'); -- NULL (UNKNOWN) ❌ ไม่ใช่ TRUE
วิธีจัดการ NULL ให้ถูกต้อง
1. ใช้ IS NULL / IS NOT NULL โดยตรง
WHERE col = 'value' OR col IS NULL
2. ใช้ COALESCE/IFNULL แปลง NULL เป็นค่าอื่น
WHERE COALESCE(col, '') IN ('value', '')
3. ใช้ <=> (Null-safe equal) — MySQL specific
WHERE col <=> 'value' -- TRUE ถ้าทั้งคู่ NULL, FALSE ถ้าต่างกัน
Best Practice
- ออกแบบ Schema ให้ NOT NULL เมื่อเป็นไปได้
- ใช้ DEFAULT แทน NULL สำหรับค่าที่ "ไม่มี"
- เขียน WHERE ให้ชัดเจน: แยกเงื่อนไข NULL ออกมา