最近在項(xiàng)目中遇到一個問題,感覺有點(diǎn)意思,在解決問題及查閱了相關(guān)資料后,打算寫篇文章給朋友們分享一下。
問題現(xiàn)象:
問題是很常見的空指針問題,后端查詢數(shù)據(jù)庫數(shù)據(jù),遍歷進(jìn)行相關(guān)業(yè)務(wù)處理時報(bào)空指針。通過斷點(diǎn)調(diào)試發(fā)現(xiàn)問題就出在查詢回來的數(shù)據(jù)上,返回的List集合中有一條空數(shù)據(jù)導(dǎo)致的。
就很納悶,怎么會返回空數(shù)據(jù)?
繼續(xù)排查
發(fā)現(xiàn)sql執(zhí)行完確實(shí)有一行空數(shù)據(jù),先給兄弟們看一下sql(業(yè)務(wù)代碼不便透露這里進(jìn)行了簡化,主要復(fù)現(xiàn)問題):
SELECT
o.order_id,
o.order_no,
o.detail_id,
o.product_id,
o.batch,
o.comp_brand_id,
o.supplier_id,
o.buyer
FROM
tr_production_purchase_contract_and_order contractOrder
LEFT JOIN t_daily_purchase_order o ON contractOrder.order_id = o.order_id
AND contractOrder.contract_id = '1585249657636917248'
AND contractOrder.del_flag = '0'
大概意思就是關(guān)聯(lián)搜索contract_id = '1585249657636917248’的數(shù)據(jù),執(zhí)行結(jié)果顯示contractOrder.contract_id = ‘1585249657636917248’ AND contractOrder.del_flag = '0’條件沒有生效。
為啥不生效?第一反應(yīng)寫錯了,仔細(xì)檢查沒有問題。于是懷疑left join on后面加條件是不是有什么特殊的,查完資料,還確實(shí)非常特殊。join on后面加條件與where條件是不一樣的。
先給結(jié)論:
-
left join
on后面條件篩選是對2張表生成的全連接(笛卡爾積)臨時表進(jìn)行的篩選,無論on后面的條件是否滿足都會返回左表的所有數(shù)據(jù),不符合條件的右表的值都為null -
right join
同上,只不過是最終返回右表的所有數(shù)據(jù),不符合條件的左表的值都為null -
inner join
inner join有點(diǎn)不一樣,它是兩張表取交集,最終的結(jié)果是符合所有條件的值,所以on后面的條件可以生效 -
where
查詢出來的結(jié)果最后都會再經(jīng)過where條件進(jìn)行過濾,滿足條件才會返回
由此可見left join 的時候,on后面對左表的數(shù)據(jù)加篩選條件是沒有用的。上面問題的原因也找到了因?yàn)橹徊樵兞擞冶淼闹?,因?yàn)椴粷M足條件,所以查詢回來的數(shù)據(jù)為空。
為了驗(yàn)證這個觀點(diǎn),我們進(jìn)行一下測試:
員工表
部門表
left join 單條件查詢
select
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id
on 后面加條件
select
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id and t.emp_id = '4';
把on的所有條件作為匹配條件,不符合的右表都為null
where 后面加條件
select
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id where t.emp_id = '4';
匹配完再篩選,結(jié)果只有一條記錄。
inner join 多條件查詢
select
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
inner join t_dept d on t.dept_id = d.dept_id where t.emp_id = '4';
總結(jié):
在連表操作的時候,其實(shí)是先進(jìn)行了2表的全連接(笛卡爾積,也就是所有能組合的情況a.rowCount*b.rowCount),然后根據(jù)on后面的條件進(jìn)行篩選,最后如果是左連接或者右連接,再補(bǔ)全左表或者右表的數(shù)據(jù)。
個人理解不一定正確,歡迎指正文章來源:http://www.zghlxwxcb.cn/news/detail-673004.html
參考文章:
join on多個條件的理解文章來源地址http://www.zghlxwxcb.cn/news/detail-673004.html
到了這里,關(guān)于Mysql join加多條件與where的區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!