一、前言
如題所示,我們有的時候直接使用左連接查詢,當右表不存在該數據的時候,是可以查出帶有null
的列。可是當在where
條件中有右表相關的篩選條件時,我們驚奇的發現查詢的結果不帶null
值了,換句話說就是查出來的結果比預期的少。
博主之前遇到過這個問題,只不過當時解決了就沒記錄。誰知道前兩天有朋友問到這個sql
,nnd
給忘記了,又耗費了大半個小時,這裏還是記錄下。
二、錯誤復現以及解決方案
1、右表不帶篩選條件的查詢
sql
相關的表主要是w_order
(訂單表)和w_a_info
(商品種類表):
SELECT
o.id ,
a.name,
o.order_time
FROM
w_a_info AS a
left JOIN w_order AS o ON a.id = o.infoid
WHERE
a.ifshow = 200
GROUP BY
a.id
結果:
id name order_time
11 好愧開語音潑猴 1574341554
12 餄烙面 1574587287
9 黃燜雞米飯 1574340342
NULL 黃燜雞1 NULL
這裏能看到,我們查詢出來的有帶有NULL
值的列。
2、右錶帶有篩選條件
SELECT
o.id ,
a.name,o.order_time
FROM
w_a_info AS a
left JOIN w_order AS o ON a.id = o.infoid
WHERE
a.ifshow = 200
and o.order_time>0
GROUP BY
a.id
結果:
id name order_time
11 好愧開語音潑猴 1574341554
12 餄烙面 1574587287
9 黃燜雞米飯 1574340342
根據結果發現,我們原來帶有null
值的列消失了,是的,是被where
中的篩選條件給篩選掉了。只是有時候我們的需求是要獲取所有的商品信息的,因此這個null
列還不能被篩選掉,不然就造成數據缺失了。
這裏推測是因爲sql
的執行順序,on
表連接是先於where
條件的,因此我們先on
連接之後,產生了不符合條件的NULL
列,然後NULL
列被where
條件給篩選掉了。這裏解決方案是把右表的篩選條件放到前面去,也就是連表的地方去。
3、左連接之後加篩選條件
SELECT
o.id ,
a.name,
o.order_time
FROM
w_a_info AS a
left JOIN w_order AS o ON a.id = o.infoid AND o.order_time>0
WHERE
a.ifshow = 200
GROUP BY
a.id
結果:
id name order_time
11 好愧開語音潑猴 1574341554
12 餄烙面 1574587287
9 黃燜雞米飯 1574340342
NULL 黃燜雞1 NULL
這裏我們把篩選條件放到連接處,通過on ... and ...
的方式,在連接時就附帶上條件,此時不符合條件的數據列還是以null
值的方式展現,並不會被後續的where
篩選條件給篩選掉。
end