MySQL LEFT JOIN含NULL值问题:保留work表customer_id为NULL的条目
解决LEFT JOIN后丢失customer_id为NULL的记录问题
嘿,这是个LEFT JOIN里非常常见的陷阱,我来帮你梳理清楚问题和解决方案:
问题根源
你用了LEFT JOIN customer,本应该保留work表中所有记录(包括customer_id = NULL的条目),但WHERE customer.visible = 0这行把这些记录过滤掉了。原因是:当work.customer_id为NULL时,LEFT JOIN后customer表的所有字段(包括visible)都会是NULL,而SQL中NULL和任何值比较的结果都是UNKNOWN,WHERE子句会自动排除这些结果,所以你看不到这些记录。
两种解决方案
方案1:将customer的过滤条件移到LEFT JOIN的ON子句中(推荐)
把customer.visible = 0从WHERE移到LEFT JOIN的关联条件里,这样只会在关联customer表时过滤出符合条件的记录,不会影响work表中customer_id为NULL的条目:
SELECT * FROM work LEFT JOIN users ON work.user_id = users.user_id LEFT JOIN customer ON work.customer_id = customer.customer_id AND customer.visible = 0; -- 把条件放在这里
这样执行后,work表中customer_id为NULL的记录会完整保留,对应的customer字段值都是NULL;而customer_id非NULL的记录,只会关联到customer表中visible=0的条目。
方案2:在WHERE子句中兼容NULL情况
如果一定要在WHERE里写条件,需要明确包含work.customer_id IS NULL的情况:
SELECT * FROM work LEFT JOIN users ON work.user_id = users.user_id LEFT JOIN customer ON work.customer_id = customer.customer_id WHERE (customer.visible = 0 OR work.customer_id IS NULL);
这个写法会同时保留两种记录:一是customer表中visible=0的匹配记录,二是work表中customer_id为NULL的记录。不过相比方案1,这种写法可能会影响查询性能(OR条件可能让索引失效),逻辑也不如方案1清晰,所以更推荐方案1。
内容的提问来源于stack exchange,提问作者webGuy
相关产品推荐
相关产品推荐

