一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Oracle外連接中對非連接條件使用(+)需要注意的地方

 melodyjian 2017-08-29

1.先來說下Oracle外連接語句中對非鏈接條件使用(+)的作用問題

之前問過朋友,當時大腦處于短路狀態(tài),居然沒想明白作用是啥。先看例子如下:

select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING';
使用scott賬戶登錄,執(zhí)行上面的sql語句,可以分析出此sql語句的意圖是將部門表和員工表進行左外鏈,找出鏈接中員工名字不為‘KING’的記錄,在emp.ename后面加上(+)后,名字為空的記錄也會列出來,即沒有員工的部門也會列出來,如果不加(+),這樣的記錄就列不出來。

2.上面是使用oracle自己的外聯(lián)結(jié)語法的sql語句,如果使用ANSIsql1992標準,即left join,那么情況會有所變化,(+)不能同時和ANSI標準的join一起使用,那么我想emp.ename后面的(+)應(yīng)該變成 emp.ename is null,(可經(jīng)過試驗,發(fā)現(xiàn)根據(jù)ename字段的類型不同,結(jié)果有所不同,一下列出幾個sql語句,供試驗,待有執(zhí)行環(huán)境后,整理之,本次只整理了varchar的情況)

--vacrchar類型
    select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename!='KING';
    select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING';

select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING';
    select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING' or emp.ename is null;

--number類型
    select * from dept,emp where dept.deptno=emp.deptno(+) and emp.empno!=7782;
    select * from dept left join emp on(dept.deptno=emp.deptno) and emp.empno!=7782;

select * from dept,emp where dept.deptno=emp.deptno(+) and emp.empno(+)!=7782;
    select * from dept left join emp on(dept.deptno=emp.deptno) and emp.empno!=7782 or emp.empno is null;
--char類型又不一樣

(以上用!='KING',用=‘KING’又將如何?)

----------------------------------------------------------------------------------------------

分析:

先列出兩張表的數(shù)據(jù)
dept:
DEPTNODNAMELOC
10ACCOUNTINGNEW YORK
20RESEARCHDALLAS
30SALESCHICAGO
40OPERATIONSBOSTON
emp:
DEPTNOEMPNOENAMEJOBMGRHIREDATESALCOMM
107782CLARKMANAGER78391981-6-92450.00 
107839KINGPRESIDENT 1981-11-175000.00 
107934MILLERCLERK77821982-1-231300.00 
207369SMITHCLERK79021980-12-17800.00 
207566JONESMANAGER78391981-4-22975.00 
207788SCOTTANALYST75661987-4-193000.00 
207876ADAMSCLERK77881987-5-231100.00 
207902FORDANALYST75661981-12-33000.00 
307499ALLENSALESMAN76981981-2-201600.00300.00
307521WARDSALESMAN76981981-2-221250.00500.00
307654MARTINSALESMAN76981981-9-281250.001400.00
307698BLAKEMANAGER78391981-5-12850.00 
307844TURNERSALESMAN76981981-9-81500.000.00
307900JAMESCLERK76981981-12-3950.00 
dept對emp做外連接后的結(jié)果是:
DEPTNODNAMELOCEMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
10ACCOUNTINGNEW YORK7782CLARKMANAGER78391981-6-92450.00 10
10ACCOUNTINGNEW YORK7839KINGPRESIDENT 1981-11-175000.00 10
10ACCOUNTINGNEW YORK7934MILLERCLERK77821982-1-231300.00 10
20RESEARCHDALLAS7369SMITHCLERK79021980-12-17800.00 20
20RESEARCHDALLAS7566JONESMANAGER78391981-4-22975.00 20
20RESEARCHDALLAS7788SCOTTANALYST75661987-4-193000.00 20
20RESEARCHDALLAS7876ADAMSCLERK77881987-5-231100.00 20
20RESEARCHDALLAS7902FORDANALYST75661981-12-33000.00 20
30SALESCHICAGO7499ALLENSALESMAN76981981-2-201600.00300.0030
30SALESCHICAGO7521WARDSALESMAN76981981-2-221250.00500.0030
30SALESCHICAGO7654MARTINSALESMAN76981981-9-281250.001400.0030
30SALESCHICAGO7698BLAKEMANAGER78391981-5-12850.00 30
30SALESCHICAGO7844TURNERSALESMAN76981981-9-81500.000.0030
30SALESCHICAGO7900JAMESCLERK76981981-12-3950.00 30
40OPERATIONSBOSTON        
最后一行,編號為40的部門是外連接的效果,emp表對應(yīng)的字段都為空
  • 首先,對于!=號,varchar
    現(xiàn)在考慮如下情況,如果想要找出所有部門中員工姓名不為King的員工和部門都找出來,并且沒有員工的部門也列出來,那么一般會想到用
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename!='KING';
這條sql語句,但是發(fā)現(xiàn)40這個部門并不在結(jié)果中,也就是說,最后一行中雖然emp的ename為空,符合!=‘KING’的條件,但卻沒有作為結(jié)果返回,似乎oracle認為這條記錄不存在,于是想要這條結(jié)果出來,那么必須在條件emp.ename!='KING'處加上一個(+)即
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING',使得好像是外聯(lián)結(jié)果產(chǎn)生的記錄中對應(yīng)于emp表的ename字段的值是任何一個不為‘KING’的字符串,這樣這條記錄便被算作是結(jié)果列了出來。
    同樣,使用ANSI語法的語句
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING'
也沒有達到效果,仍然將外聯(lián)結(jié)產(chǎn)生的記錄排除在外了,如果想要包含該條記錄,就應(yīng)該加上emp.ename is null,即
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING' or emp.ename is null
  • 其次,再來看=號的情況
    再來看這樣一個需求,如果我們想看一下每個部門及其助理的信息,并且如果該部門沒有助理的話,把部門信息列出來,助理的信息顯示空,那么我們可能會想到如下sql
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.job='ASSISTENT'
但是結(jié)果是沒有任何記錄,因為外聯(lián)結(jié)結(jié)果中沒有任何記錄符合其員工職位為ASSITENT,如果要達到我們的要求,sql語句應(yīng)該寫為
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.job(+)='ASSISTENT' ,
(+)的作用就好象是使oracle造出了這樣的外聯(lián)結(jié)記錄,部門的員工中有一個的工作職位是ASSISTENT,但因為實際并沒有這樣的記錄,所以這條記錄的emp表的字段都是空。
    我們可能希望ANSI格式的SQL語句也能達到這樣的效果,你也許可能想到加上emp.job is null不久可以了么,但是那樣只會列出外連接記錄,即部門40的記錄,部門10,20和30的記錄都不會列出來.
所以需要做如下變通,通過左外連接一個子查詢來實現(xiàn):
select * from dept left join (select * from emp where ename='ASSISTENT') t on dept.deptno=t.deptno

  • 注意:
     如上的分析是dept對emp進行左外聯(lián),外聯(lián)條件也是dept.deptno=emp.deptno(+),我們注意到(+)是加在右邊的表上,而條件中我們的(+)也是加在右邊表的字段上,而不是常量值上,如emp.job(+)='ASSISTENT' ,上面兩種情況都是對于條件是在右邊的表的情況,如果條件是在左邊的表中呢?加上(+)又是什么效果?
 
 因為左連接在沒有其他任何條件的情況下,會將左邊表中的所有記錄都列出來,實驗發(fā)現(xiàn),當條件中只有關(guān)于左邊表中的條件時,無論!=還是=的情況,不論加上(+)還是不加,效果都是一樣的,都不會有多余記錄列出。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    69精品一区二区蜜桃视频| 国产亚洲精品久久99| 午夜福利国产精品不卡| 亚洲av又爽又色又色| 国产日韩中文视频一区| 成人午夜视频在线播放| 青青久久亚洲婷婷中文网| 日韩精品一区二区不卡| 视频一区二区 国产精品| 日本加勒比中文在线观看| 精品亚洲一区二区三区w竹菊| 冬爱琴音一区二区中文字幕| 欧美日韩无卡一区二区| 亚洲国产一区精品一区二区三区色| 久久香蕉综合网精品视频| 91精品国产品国语在线不卡| 暴力三级a特黄在线观看| 国产内射在线激情一区| 日本精品中文字幕人妻| 九九热精彩视频在线免费| av一区二区三区天堂| 超薄丝袜足一区二区三区| 欧美韩日在线观看一区| 尹人大香蕉中文在线播放| 一区二区三区在线不卡免费| 日本欧美一区二区三区高清| 亚洲精品国产美女久久久99| 日韩色婷婷综合在线观看| 区一区二区三中文字幕| 99久久国产精品亚洲| 久久亚洲午夜精品毛片| 亚洲中文字幕免费人妻| 欧美日韩最近中国黄片| 欧美性高清一区二区三区视频| 又黄又色又爽又免费的视频| 亚洲一区二区三区在线免费| 大尺度剧情国产在线视频| 亚洲淫片一区二区三区| 欧美国产日产在线观看| 国内女人精品一区二区三区| 精品推荐久久久国产av|