溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

sql連接查詢中on篩選與where篩選的區(qū)別

發(fā)布時間:2020-08-06 07:55:26 來源:網(wǎng)絡 閱讀:1229 作者:sshpp 欄目:數(shù)據(jù)庫

sql查詢這個東西, 要說它簡單, 可以很簡單, 通常情況下只需使用增刪查改配合編程語言的邏輯表達能力,就能實現(xiàn)所有功能。 但是增刪查改并不能代表sql語句的所有, 完整的sql功能會另人望而生畏。 就拿比普通增刪查改稍微復雜一個層次的連接查詢來說, 盲目使用, 也會出現(xiàn)意料之外的危險結果,導致程序出現(xiàn)莫名其妙的BUG。 

 

在連接查詢語法中,另人迷惑首當其沖的就要屬on篩選和where篩選的區(qū)別了,  在我們編寫查詢的時候, 篩選條件的放置不管是在on后面還是where后面, 查出來的結果總是一樣的, 既然如此,那為什么還要多此一舉的讓sql查詢支持兩種篩選器呢?  事實上, 這兩種篩選器是存在差別的,只是如果不深挖不容易發(fā)現(xiàn)而已。

 

sql中的連接查詢分為3種, cross join,inner join,和outer join ,  在 cross join和inner join中,篩選條件放在on后面還是where后面是沒區(qū)別的,極端一點,在編寫這兩種連接查詢的時候,只用on不使用where也沒有什么問題。因此,on篩選和where篩選的差別只是針對outer join,也就是平時最常使用的left join和right join。

 

來看一個示例,有兩張數(shù)據(jù)表,結構和數(shù)據(jù)如圖所示

 

表main

sql連接查詢中on篩選與where篩選的區(qū)別

表ext

sql連接查詢中on篩選與where篩選的區(qū)別

可以把這兩張表看作是用來存放用戶信息的, main放置主要信息,ext表放置附加信息,兩張表的關系是1對1的,以id字符作為對應關系鍵?,F(xiàn)在我們需要將地址不為杭州的所有用戶信息篩選出來,結果中需要包含main表和ext表的所有字段數(shù)據(jù)。

 

 select * from main left JOIN  exton main.id = ext.id  and  address <> '杭州'

 

閉上眼睛, 請用大腦人肉運行一下這段SQL, 想象一下是什么結果。

sql連接查詢中on篩選與where篩選的區(qū)別

當把 address <> '杭州' 這個篩選條件放在on之后,查詢得到的結果似乎跟我們預料中的不同,從結果中能看出,這個篩選條件好像只過濾掉了ext表中對應的記錄,而main表中的記錄并沒有被過濾掉,也就是上圖中標記為紅色的那條記錄。outer join相對于inner join的一個主要特性就是以一側的表為基礎,但是在這里以左表為基這一點卻可以無視篩選條件,這未免也太霸道了一些。

 

把查詢語句稍微改動一下,將地址的篩選條件從on轉移至where

 

select * from main left JOIN  ext on main.id = ext.id  where address <> '杭州'

 

結果就如我們預期的那樣了

sql連接查詢中on篩選與where篩選的區(qū)別

造成這種結果上的差異要從outer join查詢的邏輯查詢的各個階段說起??偟膩碚f,outer join 的執(zhí)行過程分為4步

 

1、先對兩個表執(zhí)行交叉連接(笛卡爾積)

2、應用on篩選器

3、添加外部行

4、應用where篩選器

 

就拿上面不使用where篩選器的sql來說,執(zhí)行的整個詳細過程如下

 

第一步,對兩個表執(zhí)行交叉連接,結果如下,這一步會產(chǎn)生36條記錄(此圖顯示不全)

sql連接查詢中on篩選與where篩選的區(qū)別

第二步,應用on篩選器。篩選器中有兩個條件,main.id = ext.id  and address<> '杭州',符合要求的記錄如下

sql連接查詢中on篩選與where篩選的區(qū)別

這似乎正是我們期望中查詢的結果,然而在接下來的步驟中這個結果會被打亂

 

第三步,添加外部行。outer join有一個特點就是以一側的表為基,假如另一側的表沒有符合on篩選條件的記錄,則以null替代。在這次的查詢中,這一步的作用就是將那條原本應該被過濾掉的記錄給添加了回來

sql連接查詢中on篩選與where篩選的區(qū)別

是不是不種畫蛇添足的感覺, 結果就成了這樣

sql連接查詢中on篩選與where篩選的區(qū)別

第四步,應用where篩選器

 

在這條問題sql中,因為沒有where篩選器,所以上一步的結果就是最終的結果了。

 

而對于那條地址篩選在where條件中的sql,這一步便起到了作用,將所有地址不屬于杭州的記錄篩選了出來

 sql連接查詢中on篩選與where篩選的區(qū)別

通過上面的講解,已經(jīng)能反應出在outer join中的篩選條件在on中和where中的區(qū)別,開發(fā)人員如能詳細了解之中差別,能規(guī)避很多在編寫sql過程中出現(xiàn)的莫名其妙的錯誤。


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI