您好,登錄后才能下訂單哦!
錯(cuò)誤使用LEFTJOIN 導(dǎo)致錯(cuò)誤數(shù)據(jù)釋疑的示例分析,相信很多沒有經(jīng)驗(yàn)的人對(duì)此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
昨天,公司的某位熟悉業(yè)務(wù)和SQL的人員,著急忙慌的找我,說必須要解決一個(gè)線上的SQL的問題,發(fā)現(xiàn)數(shù)據(jù)對(duì)不上了,搞不定挨批事小,但數(shù)據(jù)錯(cuò)誤事關(guān)重大。責(zé)無旁貸的趕緊和他一起分析這個(gè)SQL。
其實(shí)就是兩個(gè)表,一個(gè)表中有另一個(gè)表的關(guān)聯(lián)鍵,你可以認(rèn)為是主外鍵關(guān)系(這里僅僅是關(guān)系,我沒有說是主外鍵,或者絕對(duì)一一對(duì)應(yīng))。他的問題是
為什么兩個(gè)表單表查詢的數(shù)據(jù)是正確了,只要一left join 就有NULL空數(shù)據(jù),這是已經(jīng)上線多時(shí)的一個(gè)SQL 語句,今天突然發(fā)現(xiàn)對(duì)賬的結(jié)果不對(duì)??????
OK,生產(chǎn)數(shù)據(jù)一定是不能拿來做演示的,這里就簡(jiǎn)單的建兩個(gè)表,來說明這個(gè)問題,兩個(gè)表
這里用SIZE_1 和 SIZE_2 來做連接,原來生產(chǎn)的SQL是類似這樣的寫法(實(shí)際當(dāng)中比這個(gè)要復(fù)雜的多,5個(gè)表的LEFT JOIN 加6-7個(gè)條件)
select tab1.*,tab2.*
from tab1 as tab1
left join tab2 as tab2 on tab1.size_1 = tab2.size_2 and tab2.name = 'aaa'
這位工作人員的問題就是為什么會(huì)出現(xiàn)NULL ,他希望出現(xiàn)的結(jié)果是
我和他解釋,出現(xiàn)上面NULL的結(jié)果是很正常的,原因是程序員沒有明白LEFT JOIN 和 后面直接給條件 和 下寫法的區(qū)別,認(rèn)為兩個(gè)是相等的
這里程序員把條件寫到上面可能是收到數(shù)據(jù)庫優(yōu)化的知識(shí)的影響,知道SQL優(yōu)化器執(zhí)行的順序(這里不在多講)
我和這位工作人員解釋,出現(xiàn)錯(cuò)誤結(jié)果就是講這個(gè)條件放到LEFT JOIN 后,造成的。
我給他解釋了一下大致的原因,下面的圖能很好的詮釋三種寫法查詢后的數(shù)據(jù),以及造成數(shù)據(jù)錯(cuò)誤的原因。大家可以很清晰的看到,只有第一種寫法造成查詢結(jié)果和預(yù)期不一致。
1、 on條件是在生成臨時(shí)表時(shí)使用的條件,它不管on中的條件是否為真,都會(huì)返回左邊表中的記錄。
2、where條件是在臨時(shí)表生成好后,再對(duì)臨時(shí)表進(jìn)行過濾的條件。這時(shí)已經(jīng)沒有l(wèi)eft join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過濾掉。
而left join,right join,full join的特殊性,不管on上的條件是否為真都會(huì)返回left或right表中的記錄,full則具有l(wèi)eft和right的特性的并集。 而inner jion沒這個(gè)特殊性,則條件放在on中和where中,返回的結(jié)果集是相同的。
看完上述內(nèi)容,你們掌握錯(cuò)誤使用LEFTJOIN 導(dǎo)致錯(cuò)誤數(shù)據(jù)釋疑的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。