博客 > SQL知識:圖解SQL中的where和on的區(qū)別
瀏覽量:1242次評論:0次
作者:銳成網(wǎng)絡(luò)整理時間:2024-06-25 16:43:43
SQL中關(guān)聯(lián)條件是放where后面好,還是on后面好?今天就通過圖形的方式給大家來解決這個問題。以下是圖解SQL中的where和on的區(qū)別的全部內(nèi)容。
測試樣表
我們新建兩張測試表Customers和Orders,表結(jié)構(gòu)如下:
表Customers
表Orders
要求:使用SQL查詢廣州客戶的相關(guān)信息(客戶ID,姓名,地址,城市,郵編,省份,訂單ID)
我們直接寫出正確的SQL查詢語句:
SELECT a.*,b.訂單ID FROM Customers a
LEFT JOIN Orders b ON a.客戶ID=b.客戶ID
WHERE a.城市='廣州'
結(jié)果如下:
OK,我們的問題是:
既然ON和WHERE都是過濾篩選條件的,那么能不能將WHERE后面的條件 a.城市='廣州' 放在 ON條件后面呢?
這里要分情況來看:
如果是內(nèi)連接(inner join)是可以直接放ON后面的,與放在WHERE后面的效果是相同的。
我們以下面的例題來講解:
因?yàn)樵趕ql的內(nèi)連接階段,左表(a)和右表(b)通過笛卡爾積生成的虛表VT-A1,
VT-A1
在經(jīng)過內(nèi)連接后會將虛表VT-A1中符合條件
(a.CustomerID=b.CustomerID)的左右表完成篩選,最后得到虛表VT-A2,如下圖
VT-A2
這樣就沒有添加外部行的動作了,不管其它過濾條件是放在ON后面還是WHERE 后面,都只是對VT-A2進(jìn)行進(jìn)一步的過濾,ON和WHERE的效果沒有任何差別。
但如果是左右連接則只能放在WHERE后面,這是為什么呢?
回到最開始的例題,我們可以先看下將 a.城市='廣州' 條件放到 ON后面看下結(jié)果:
SELECT a.*,b.訂單ID FROM Customers a
LEFT JOIN Orders b ON a.客戶ID=b.客戶ID AND a.城市='廣州'
結(jié)果為:
與你想的結(jié)果是不是完全不同?
這是因?yàn)樵趫?zhí)行sql左連接的時候,是先執(zhí)行的ON后面的所有條件。
從上述的代碼我們可以知道,先將Customers表與Orders表的客戶ID進(jìn)行內(nèi)連接,這個時候得到的是下面的這個虛表VT-B1的結(jié)果
虛表VT-B1
然后再接著加上了一個 and a.城市='廣州' 這個條件,那么我們會對上面的這個虛表VT-B1進(jìn)一步過濾,得到虛表 VT-B1-1
虛表VT-B1-1
執(zhí)行完虛表VT-B1-1后,根據(jù)我們LEFT JOIN的原理,我們是要將左表(Customers表)未關(guān)聯(lián)上的其它所有數(shù)據(jù)都要添加到虛表VT-B1-1中的,所以在執(zhí)行完LEFT動作之后,它的結(jié)果變成了虛表VT-B2。
這個時候除了虛表VT-B1-1的訂單ID非空,其它Customers表中被添加的數(shù)據(jù)行對應(yīng)的訂單ID均為空。
虛表VT-B2
即我們上述sql代碼的錯誤結(jié)果。
那為什么 a.城市='廣州' 放在WHERE后面結(jié)果又是正確的呢?
因?yàn)樵贚EFT JOIN結(jié)束后的階段后:
SELECT a.*,b.訂單ID FROM Customers a
LEFT JOIN Orders b ON a.客戶ID=b.客戶ID
我們得到的虛表VT-C1是如下這樣的:
虛表VT-C1
注意看:
虛表VT-C1與上面錯誤結(jié)果虛表VT-B2的區(qū)別,上面的虛表VT-B2在訂單ID列,只有城市為廣州的非空,而VT-C1只要匹配上客戶ID的訂單ID均非空
而我們的WHERE條件 a.城市='廣州' 就是對VT-C1進(jìn)行篩選,得到如下虛表VT-C2
虛表VT-C2
因?yàn)槭亲詈笠徊?,所以sql的查詢分析器會直接將VT-C2的結(jié)果返回給查詢發(fā)起者,所以我們得到的最終正確結(jié)果就是虛表VT-C2.
在理解了LEFT JOIN,RIGHT JOIN和INNER JOIN的原理后,再來看WHERE和ON的區(qū)別就比較容易理解了。
結(jié)論
1、對于內(nèi)連接(inner join),sql過濾條件放在where或者on后面沒有區(qū)別
2、對于左右連接(left/right join),sql過濾條件放在where或者on后面有很大的區(qū)別。
重要聲明:本文來自SQL數(shù)據(jù)庫開發(fā),經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有,不代表銳成觀點(diǎn),轉(zhuǎn)載的目的在于傳遞更多知識和信息。
相關(guān)文章推薦
2025-05-27 11:53:22
2024-08-20 17:58:16
2024-08-19 17:49:29
2024-08-19 10:23:28
2024-08-16 17:06:33
熱門工具
標(biāo)簽選擇
閱讀排行
我的評論
還未登錄?點(diǎn)擊登錄