这是最好的时代,这是最坏的时代,这是智慧的时代,这是愚蠢的时代;这是信仰的时期,这是怀疑的时期;这是光明的季节,这是黑暗的季节;这是希望之春,这是失望之冬;人们面前有着各样事物,人们面前一无所有;人们正在直登天堂;人们正在直下地狱。 我也要与时俱进了,被itpub2.0牵着尾巴,拼命的奔跑,不停的灌水...

【原】Oracle中Left Outer Join和外关联(+)的区别

上一篇 / 下一篇  2008-03-23 16:22:37 / 个人分类:数据库专区

查看( 456 ) / 评论( 11 )

 

外关联是Oracle数据库的专有语句

Left Outer Join则是SQL-92的标准语句

通常认为这两个SQL是可以等效的,但还是有些细微的差别。

一般说来,外关联的等值条件等效于Left Outer Join中的on语句;两个where中其他语句是一样的。

但是Left Outer Join中的其他条件(非表连接)出现在On关键词后面还是出现在Where关键词后面是不一样的,这样的语句很难用外关联进行同义转义。

 

下面我们先看一个测试数据,和一个测试案例

创建一个部门表和员工表

CREATE TABLE departments

(

 depID  NUMBER(38,0),

 depName VARCHAR2(20),

 delFlag NUMBER(1,0)

);

 

CREATE TABLE employees

(

 empID  NUMBER(38,0),

 empName VARCHAR2(20),

 depID  NUMBER(38,0),

 delFlag NUMBER(1,0)

);

 

INSERT INTO departments VALUES(1,'Finacle',0);

INSERT INTO departments VALUES(2,'Marketing',0);

INSERT INTO departments VALUES(3,'HR',1);

INSERT INTO departments VALUES(4,'IT',0);

 

INSERT INTO employees VALUES(1,'wbq',1,0);

INSERT INTO employees VALUES(2,'czh',2,0);

INSERT INTO employees VALUES(3,'chh',1,0);

INSERT INTO employees VALUES(4,'wal',2,0);

INSERT INTO employees VALUES(5,'ddd',3,0);

 

COMMIT;

 

以下为测试例子

--列出部门ID3的部门和员工信息,不管该部门是否有员工

SELECT d.depID,d.depName,e.empName

 FROM departments d

 LEFT OUTER JOIN employees e

   ON d.depID = e.depID

 WHERE d.depID =3

 ORDER BY d.depID;

--和上面等效

SELECT d.depID,d.depName,e.empName

 FROM departments d, employees e

 WHERE d.depID = e.depID(+)

  AND d.depID =3

 ORDER BY d.depID;

 

--该例子可能不是很恰当,d.depID=3表示首先进行全左连接,然后查找depID=3的纪录,如果该部门中找不到对应的员工,则该部门员工则为NULL,同时都显示部门信息。

SELECT d.depID,d.depName,e.empName d.delflag

 FROM departments d

 LEFT OUTER JOIN employees e

   ON d.depID = e.depID AND e.depID=3

 ORDER BY d.depID;

--和上面不等价,差别在于能够找到无对应员工的部门和有对应员工的部门,却找不到该部门无员工的部门。

SELECT d.depID,d.depName,e.empName,d.delflag

 FROM departments d, employees e

 WHERE d.depID = e.depID(+)

  AND (e.depID=3 or e.depID is NULL)

 ORDER BY d.depID;

 


TAG:

wdollar发布于2008-03-23 16:35:18
最后那个写成这个样子就可以了
7}$?$_9QIg'^ dspace.itpub.netSELECT d.depID,d.depName,e.empName,d.delflag
:~o!OWH] uspace.itpub.net  FROM departments d, employees e
+t1cW)MLRf0W1_space.itpub.netWHERE d.depID = e.depID(+) 'LNa/o        BNZ
   AND e.depID(+)=3
-[%iT!d$Bz9_s/eORDER BY d.depID;
zhangweicai74的个人空间 zhangweicai74 发布于2008-03-23 16:40:02
星期天还这么努力,
"xD7?)p%V b})v学习了
不胜人生一场醉 bq_wang 发布于2008-03-23 16:43:45
好像不全等效,你试试这个
0J5r$s1z V,i0V}*vspace.itpub.netoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net.d'~,a-P0~        | P9M+C
Create Table student
%R*d7Z"^&zoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net(oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net
i]k+f
n(G+c[t

StuId Number(38,0),ITPUB个人空间^.SI
Z*W

StuName Varchar2(20)space.itpub.netd[7Y}Y/h@x#@
);.k+k5?*Z:Z6T0I
Create Table StuClassspace.itpub.netU:Z5e!z%S0bPQ
W9l

(

IKA:}3a ]
ClsId Number(38,0),ITPUB个人空间XWoV8m-TqI
ClsName Varchar2(20)oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net*e9HjJj x-h5mr|8M(hX
);space.itpub.netp+N:uPH
Create Table Grade
3F+|
rdq4Hkr*dh
(StuID Number(38,0),
~k/M{#P,{:yITPUB个人空间ClsID Number(38,0),
/S!Ik6~;l+Q1boracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netGradetype Varchar2(20)LF+y9Cl]d
);ITPUB个人空间xHC-VC.M-?
Insert Into student Values(1,'甲');
W}1ro,N K3[WrITPUB个人空间Insert Into student Values(2,'乙');
W9P}@_espace.itpub.netInsert Into StuClass Values(1,'语文');
:u7wlo5N)aoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netInsert Into StuClass Values(2,'数学');
)fY(B[;@-g"O:W'WUInsert Into StuClass Values(3,'英语');  
0_p
P_Vp
Insert Into Grade Values(1,1,'A');
+G0|7R&X
qA;s2{!pl
Insert Into Grade Values(1,2,'B'); space.itpub.net!UG&]!Tbv/z
Insert Into Grade Values(2,1,'A'); *mg0OU
TCx4w0XH

Commit;
r.{.A;x U4v/Foracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netspace.itpub.net+jb1\g~R
Select stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetypeITPUB个人空间y;EEw:Ya@
From student stu
+Y`p7b
Kb.mMkITPUB个人空间
Left Join grade grd On grd.stuid=stu.stuid And grd.gradetype='B'
%LB*rE'zrY]ITPUB个人空间Left Join stuclass cls On grd.clsid =cls.clsid
8_%J1@-emo
"_S-D8n8H#woracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netP0G6wj!|%VtL@
Select stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetype
!c dx2?Grn_        aoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netFrom student stu,grade grd ,stuclass cls2`Y;x&lMC8RO
where stu.stuid(+)=grd.stuid And grd.gradetype(+)='B'oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netiJIi#_Nk
and grd.clsid =cls.clsidoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net4an9Io%neI

6^r$A"d
T*n1Koracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net

QUOTE:

原帖由 wdollar 于 2008-3-23 16:35 发表 ,GYA C5C-mM
最后那个写成这个样子就可以了
)\:Tu1o C1YITPUB个人空间SELECT d.depID,d.depName,e.empName,d.delflagspace.itpub.net z0VG9w0{6A`#F
a

  FROM departments d, employees e
uL        S(tW9k"G eITPUB个人空间WHERE d.depID = e.depID(+) 9L!Qu.N_"nJ|r
   AND e.depID(+)=3
'\Xw8a"o-Q"Q^0aORDER BY d.depID;

不胜人生一场醉 bq_wang 发布于2008-03-23 16:45:15
上周5帮同事写的,感觉这两个语法还是不能全等效的 oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net7U7G,j6J#gs$t.zi

1YK1NCr+ERl;fl_        xcspace.itpub.net你不用向我这个菜鸟学习啊
Tg(V+pA2C7~lw
q2mgE1a0h!D        G

QUOTE:

原帖由 zhangweicai74 于 2008-3-23 16:40 发表 oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net Ip?9^Av
星期天还这么努力,ITPUB个人空间i4w/as)Z~
学习了

wdollar发布于2008-03-23 17:10:47

QUOTE:

原帖由 bq_wang 于 2008-3-23 16:43 发表
-p K'}]0sA3A;horacle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net好像不全等效,你试试这个
OLT/C~0r/Eoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netspace.itpub.net5GoX4_~;D/r        o
Create Table studentITPUB个人空间F]y*X8E?
(
fM\ee+qw4cStuId Number(38,0),
%bk_}~Tb0eStuName Varchar2(20)%d-dX9y4T"n~#G*a
);
(C}}:Y^-jxn{jspace.itpub.netCreate Table StuClass:i&dj9`:s        E
(        x9Z^;_z
mW?

ClsId Number(38,0),oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net!F6W4_(ub!L5dXG;I
ClsName Varchar2(20)space.itpub.net[ x$cbz1D
);7xD)UB6^y
Create Table Grade
j.t^S6aw#ytporacle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net(StuID Number(38,0),+T'S3v/`jp)nbL&R
ClsID Number(38,0),space.itpub.net        MQj9@K:]1DUj:{
Gradetype Varchar2(20)
:tBV8}T~oracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net);O,{5w5}dd3K8P
Insert Into student Values(1,'甲');{o6y4}N
MG

Insert Into student Values(2,'乙');.j
K[
p#~j

Insert Into StuClass Values(1,'语文');
urI }$^];w!I        m_(zspace.itpub.netInsert Into StuClass Values(2,'数学');ITPUB个人空间DU;]gxY6O
Insert Into StuClass Values(3,'英语');  JR8u1WmX5ty;K8]
Insert Into Grade Values(1,1,'A');space.itpub.net$P"e)u[T
Insert Into Grade Values(1,2,'B'); A h5S4`jR*_
Insert Into Grade Values(2,1,'A'); N} ky(nQh/PwC#`
Commit;{c&_+c3U&J

p8h;}Y7`'^4Loracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netSelect stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetypev
h2NF'h/Y9m!S#?9e

From student stu6y~        pih}.~8D'n
Left Join grade grd On grd.stuid=stu.stuid And grd.gradetype='B'-Hh~%GNj#S6U
Left Join stuclass cls On grd.clsid =cls.clsid
*Q{ kN,Y S~`r
{_Gf;uxS
0Q FC {#o6q-\$d8M)QESelect stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetypeoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net;a1hxoP]O3K
From student stu,grade grd ,stuclass cls0Go]$P"m"C%z
where stu.stuid(+)=grd.stuid And grd.gradetype(+)='B'space.itpub.net.vV:^0T`/g0Q7p
and grd.clsid =cls.clsid
V
RJ        W)X^


qr5`T'a
Pu1m
3L^-?v%?i{space.itpub.net}q5Ki6A
^(R].gpY

参照第一个SQL,第二个SQL中where语句的第一个条件似乎有误。ITPUB个人空间ug/T hc(l!y
这种多表的关联我也没写过,不过下面这个SQL的结果和第一个SQL一致:_-d:R/g'Z B6L,s:s

2JX'`QDJ?
mIITPUB个人空间
Select stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetypeD)@#zaF
From student stu,grade grd ,stuclass clsspace.itpub.netF-`"LkXV
where stu.stuid=grd.stuid(+) And grd.gradetype(+)='B'space.itpub.netEQ:@x3K)TM        W
and grd.clsid =cls.clsid(+)
不胜人生一场醉 bq_wang 发布于2008-03-23 17:56:09
tks
q9{$O'H$y1y+Gm?ITPUB个人空间
Nm6ly?1Boracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net

QUOTE:

原帖由 wdollar 于 2008-3-23 17:10 发表 ITPUB个人空间2^B.u O7ly(q5DQ

[ e'[C)O;|*lgITPUB个人空间 s{P$C&@{(Zq4N
参照第一个SQL,第二个SQL中where语句的第一个条件似乎有误。ITPUB个人空间
T\9P@ w1@I

这种多表的关联我也没写过,不过下面这个SQL的结果和第一个SQL一致:
9K%N6?0L
D(Tx4^5Z

,rP/i$[EhtITPUB个人空间Select stu.stuid,stu.stuname,cls.clsid,cls.clsname,grd.stuid,grd.clsid,grd.gradetype
nB9DJN/aspace.itpub.netFrom student stu,grade grd ,stuclass cls
5V^1|rV[where stu.stuid=grd.stuid(+) And grd.gradetype(+)='B'space.itpub.net{ UFW#P[8|
and grd.clsid =cls.clsid(+)

java2001发布于2008-03-23 20:26:55
但这个不代表Oracle中Left Outer Join和外关联(+)有区别
2`L        C O[%rtoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.netSELECT d.depID,d.depName,e.empName d.delflagoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net,{`iH7y X9oD+VN
  FROM departments d 4gah|m&IC"D
  LEFT OUTER JOIN employees eoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net"g!{J.M0q,W9T}
    ON d.depID = e.depID AND e.depID=3
j a:JwjzORDER BY d.depID; J j%Vv*CEc8Ne
中你没有和employees 做外关连,而是和S;s        _ N6_7U
select * from employees where depID=3
x'H5`3Q/~C:F)x3vzITPUB个人空间的结果集做了外关联
komman的个人空间 komman 发布于2008-03-24 11:04:50
难道ORACLE 的外关联不是外关联?
komman的个人空间 komman 发布于2008-03-24 11:05:36
反正我在ORACLE 里没去用LEFT OUTER JOIN
,x^3CAZO}"O_.CXspace.itpub.net一直使用(+)5w2ZlH0|\
没出现过什么问题
静·谧 lastwinner 发布于2008-03-24 13:09:45
楼主概念不清晰,鉴定完毕
jzl780821的个人空间 jzl780821 发布于2008-03-24 14:25:58
left(right/full) outer join
9g        z-c3S*E1g        b关键字能明晰地区分左外、右外、全连接的对象,即关键字的左面、右面的对象。全外连接则是两侧的对象。
sr%bd%Y!x.G5]M9ospace.itpub.net这是标准的ANSI的写法。
(`!il@+f!Uoracle,db2,sqlserver,sybase,mysql,erp,scm,sap,java,.net
O0A)p+vd^!F而外部连接运算符(+)在连接中应用时所得的左外、右外(没有全外连接)称呼则是由其在连接的条件表达式运算符的左侧还是
"zu-r1LLs右侧来确定(仅仅是称呼),那么至于Oracler如何决定运算规则则是根据外部连接运算符是限定的那张表的哪个字段来进行连接的。(即当外部运算符限定的是同一个表的同一个字段,那么不管它写在条件运算符的左侧(叫左外部连接)还是右侧(叫右外连接),结果是一样的))|+y:N"_5S
这是oracle中的传统写法。
我来说两句

(可选)

日历

« 2008-05-10  
    123
45678910
11121314151617
18192021222324
25262728293031

数据统计

  • 访问量: 13273
  • 日志数: 50
  • 建立时间: 2007-12-07
  • 更新时间: 2008-05-08

RSS订阅

Open Toolbar