核心原则:NULL和任何值比较(=、!=、>、<),结果都是NULL,不是TRUE也不是FALSE。
1、NULL = NULL 返回NULL
正确的NULL判断
-- ❌ 错误写法
SELECT * FROM user WHERE phone = NULL;
-- 0 rows(查不到任何数据)SELECT * FROM user WHERE phone != NULL;
-- 0 rows(也查不到任何数据)-- ✅ 正确写法
SELECT * FROM user WHERE phone IS NULL;
-- 查到phone为NULL的行 ✅SELECT * FROM user WHERE phone IS NOT NULL;
-- 查到phone不为NULL的行 ✅
2、COUNT(column)不统计NULL
INSERT INTO test_count VALUES
(1, 'alice', '13800138000'),
(2, 'bob', NULL),
(3, 'charlie', NULL),
(4, 'david', '15000150000');-- 统计有手机号的用户数
SELECT COUNT(phone) FROM user; -- 8(有8个用户填了手机号)-- 统计没有手机号的用户数
SELECT COUNT(*) - COUNT(phone) FROM user; -- 2(有2个用户没填)-- 或者
SELECT COUNT(*) FROM user WHERE phone IS NULL; -- 2
3、SUM/AVG也会忽略NULL
4、NOT IN遇到NULL全军覆没
WHERE user_id NOT IN (100, 200, NULL)
解决方案
- 过滤掉NULL
SELECT * FROM user
WHERE user_id NOT IN (SELECT blocked_user_id FROM blacklist WHERE blocked_user_id IS NOT NULL -- 关键
);
- 用NOT EXISTS(推荐)
SELECT * FROM user u
WHERE NOT EXISTS (SELECT 1 FROM blacklist b WHERE b.blocked_user_id = u.user_id
);-- NOT EXISTS不受NULL影响 ✅
- 用LEFT JOIN
SELECT u.*
FROM user u
LEFT JOIN blacklist b ON u.user_id = b.blocked_user_id
WHERE b.blocked_user_id IS NULL;