日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

SQL左右連接中的on and和on where的區(qū)別

 wenasunny 2017-04-28

       原先一直對(duì)SQL左右連接中的on and和on where的區(qū)別不是太了解,直到在網(wǎng)上看到了下面這段話才豁然開(kāi)朗。

        在使用left join時(shí),on and和on where條件的區(qū)別如下:  
1、on條件是在生成臨時(shí)表時(shí)使用的條件,它不管on中的條件是否為真,都會(huì)返回左邊表中的記錄。  
2、where條件是在臨時(shí)表生成好后,再對(duì)臨時(shí)表進(jìn)行過(guò)濾的條件。這時(shí)已經(jīng)沒(méi)有l(wèi)eft join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過(guò)濾掉,on后的條件用來(lái)生成左右表關(guān)聯(lián)的臨時(shí)表,where后的條件對(duì)臨時(shí)表中的記錄進(jìn)行過(guò)濾。


實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),接下來(lái)用實(shí)驗(yàn)來(lái)證明一下:

先上表結(jié)構(gòu)以及數(shù)據(jù):

  1. SQL> create table A (id int, type int);  
  2. SQL> select * from A;  
  3.         ID       TYPE  
  4. ---------- ----------  
  5.          1          1  
  6.          2          1  
  7.          3          2  
  8.   
  9. SQL> create table B(id int ,class int);  
  10. SQL> select * from B;  
  11.   
  12.         ID      CLASS  
  13. ---------- ----------  
  14.          1          1  
  15.          2          2  

  1. SQL> select * from A left join B on A.id = B.id where A.type = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
  6.          2          1          2          2  
根據(jù)上面那段話的解釋,where字句是在生成臨時(shí)表以后再進(jìn)行過(guò)濾的,也就是可以理解為就是一個(gè)左連接:select * from A left join B on A.id = B.id;

其運(yùn)行結(jié)果如下:

  1. SQL> select * from A left join B on A.id = b.id;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
  6.          2          1          2          2  
  7.          3          2  

然后加上where A.type = 1對(duì)臨時(shí)表進(jìn)行過(guò)濾,除掉A.type不為1的,顯然結(jié)果正確。


  1. SQL> select * from A left join B on A.id = B.id and A.type = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
  6.          2          1          2          2  
  7.          3          2  
因?yàn)樽筮B接不管on and語(yǔ)句是否為真都必須返回左表所有的記錄,所以and A.type=1;沒(méi)有起到任何作用。



  1. SQL> select * from A left join B on A.id = B.id and B.class = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
  6.          3          2  
  7.          2          1  
根據(jù)上面那段話的解釋:on條件是在生成臨時(shí)表時(shí)使用的條件,它不管on中的條件是否為真,都會(huì)返回左邊表中的記錄。顯然左連接再加上新的條件:B.class = 1篩選掉第二行記錄,結(jié)果正確。


  1. SQL> select * from A left join B on A.id = B.id where B.class = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
原因通①。(①,②)和(③,④)就是關(guān)鍵詞on and和on where的區(qū)別,但結(jié)果卻完全不同。綜上三個(gè)例子,where是生成臨時(shí)表以后再進(jìn)行過(guò)濾,對(duì)左右表都進(jìn)行篩選。而and后面的語(yǔ)句如果是對(duì)left join中的左表進(jìn)行過(guò)濾將不起任何作用,對(duì)右表進(jìn)行過(guò)濾的話,那么左表還是返回所有行,只是右表會(huì)被過(guò)濾掉一部分行。


再來(lái)看看內(nèi)連接inner join  on and和 on where的區(qū)別:

由于剛開(kāi)始表的數(shù)據(jù)不是太適合,所以先稍微更新一下,這樣更好觀察inner join和left join在and和where的不同之處。

  1. SQL> update A set type = 2 where id = 1;  
  2.   
  3. 已更新 1 行。  
  4.   
  5. SQL> select * from A;  
  6.   
  7.         ID       TYPE  
  8. ---------- ----------  
  9.          1          2  
  10.          2          1  
  11.          3          2  
  12.   
  13. SQL> select * from B;  
  14.   
  15.         ID      CLASS  
  16. ---------- ----------  
  17.          1          1  
  18.          2          2  
先看看and的:

  1. SQL> select * from A inner join B on A.id = B.id and A.type = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          2          1          2          2  
顯然輸出結(jié)果與左連接的不一樣,先與沒(méi)有and的內(nèi)連接比較一下:

  1. SQL> select * from A inner join B on A.id = B.id;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          2          1          1  
  6.          2          1          2          2  

顯然如果按左連接的邏輯,這個(gè)結(jié)果就是錯(cuò)誤的。但這是Oracle輸出的,而不是我瞎打的,顯然在內(nèi)連接時(shí)與左連接不同了。這里on and條件和on where條件一樣對(duì)生成以后的臨時(shí)表同樣會(huì)被過(guò)濾。顯然A表id為1的type不為1,所以它被過(guò)濾了。


再上幾組來(lái)驗(yàn)證一下上面這個(gè)猜想是否是正確的:

再來(lái)看看內(nèi)連接的where:

  1. SQL> select * from A inner join B on A.id = B.id where A.type = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          2          1          2          2  
這個(gè)也是和左連接一樣生成臨時(shí)表然后進(jìn)行過(guò)濾,不作解釋。

  1. SQL> select * from A inner join B on A.id = B.id and B.class = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          2          1          1  

  1. SQL> select * from A inner join B on A.id = B.id where B.class = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          2          1          1  
對(duì)比發(fā)現(xiàn):(⑤,⑥)和(⑦,⑧)結(jié)果都一樣,也就是說(shuō)內(nèi)連接inner join on and 或者on where不管是對(duì)左表還是右表進(jìn)行過(guò)濾,實(shí)際都是在生成臨時(shí)表以后再進(jìn)行過(guò)濾的,而且對(duì)左表和右表都起作用,這與左連接left join有本質(zhì)的區(qū)別!??!

最后上倆沒(méi)有使用連接語(yǔ)句的例子:

  1. </pre><p></p><pre name="code" class="sql">SQL> select * from A,B where A.id = B.id and A.type = 1;  
  2.   
  3.         ID       TYPE         ID      CLASS  
  4. ---------- ---------- ---------- ----------  
  5.          1          1          1          1  
  6.          2          1          2          2  
  7.   
  8.   
  9.   
  10. SQL> select * from A,B where A.type = 1 and A.id = B.id;  
  11.   
  12.         ID       TYPE         ID      CLASS  
  13. ---------- ---------- ---------- ----------  
  14.          1          1          1          1  
  15.          2          1          2          2  

比較簡(jiǎn)單,不作解釋。


總結(jié)一下:

        在使用left join時(shí),on和where條件的區(qū)別如下:  
1、on條件是在生成臨時(shí)表時(shí)使用的條件,它不管on中的條件是否為真,都會(huì)返回左邊表中的記錄。(實(shí)際上左連接中如果and語(yǔ)句是對(duì)左表進(jìn)行過(guò)濾的,那么不管真假都不起任何作用。如果是對(duì)右表過(guò)濾的,那么左表所有記錄都返回,右表篩選以后再與左表連接返回)  
2、where條件是在臨時(shí)表生成好后,再對(duì)臨時(shí)表進(jìn)行過(guò)濾的條件。這時(shí)已經(jīng)沒(méi)有l(wèi)eft join的含義(必須返回左邊表的記錄)了,條件不為真的就全部過(guò)濾掉,on后的條件用來(lái)生成左右表關(guān)聯(lián)的臨時(shí)表,where后的條件對(duì)臨時(shí)表中的記錄進(jìn)行過(guò)濾。

        在使用inner join時(shí),不管是對(duì)左表還是右表進(jìn)行篩選,on and和on where都會(huì)對(duì)生成的臨時(shí)表進(jìn)行過(guò)濾。


相關(guān)文章:SQL joins


尊重版權(quán),轉(zhuǎn)載請(qǐng)不要?jiǎng)h除下方二維碼并注明本文鏈接:http://blog.csdn.NET/xingzhemoluo/article/details/39677891


                                            歡迎關(guān)注行者摩羅微信公眾號(hào)(xingzhemoluo),共同交流編程經(jīng)驗(yàn),掃描下方二維碼即可;





    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多