Oracle在同一列

时间:2016-04-14 10:25:39

标签: sql oracle join

有人可以向我解释为什么下面的查询在描述字段中返回null

Table A:

OCD CCD 
A   B
C   D
E   F

Table B:
CD   DESCRIP
A    AL
B    BL
C    CL
D    DL
E    EL
F    FL

Result:
OCD  DESCRIP CCD DESCRIP
A    AL      B   BL
C    CL      D   DL
E    EL      F   FL

查询不正确:尽管此查询正确运行。它没有给出描述值。

select a.ocd,b.DESCRIP,a.CCD,b.DESCRIP
from A a, B b
where a.ocd=b.cd(+)
and a.ccd=b.cd(+);

正确查询

select a.ocd,b.DESCRIP,a.CCD,b.DESCRIP
from A a, B b1, B b2
where a.ocd=b1.cd(+)
and a.ccd=b2.cd(+);

3 个答案:

答案 0 :(得分:3)

您需要查找两次值,因为您有两个代码。这需要两个连接,如果可能存在不匹配,则应为left join

select a.ocd, b1.DESCRIP, a.CCD, b2.DESCRIP
from A left join
     B b1
     on a.ocd = b1.cd left join
     B b2
     on a.ccd = b2.cd;

第一个查询中的条件是:

where a.ocd=b.cd(+) and a.ccd=b.cd(+);

看看他们。它们暗示在任何匹配的行a.ocd = a.ccd中,并且在数据中的任何行上都不是这样。因此,没有匹配,结果是NULL

此外,学会使用正确的显式JOIN语法。显式连接更强大,更便携,更易于阅读。此外,Oracle多年前就弃用了(+)语法,这意味着即使Oracle将来也可能不支持它。

答案 1 :(得分:1)

从您所谓的“正确查询”中,您似乎想要从表A中选择每一行,然后对于该行中的每个值,在表B中的一行中对应的值。在第一个查询中,您在哪里连接表A和表B,连接条件要求表A中的行中的两个值在表B中的相同行中匹配。显然,这不符合您的规范。如果要将表A中的一行与表B中的两行(通常是DIFFERENT)匹配,则需要将表A与表B连接两次,如同正确的查询一样。

当您连接两个表时,将检查来自第一个表的ONE ROW和来自第二个表的ONE ROW的所有组合以查看是否满足连接条件。当您连接三个表时,将根据连接条件检查三个表中每个表的ONE ROW的所有组合。这就是你在连接中需要两次表B的原因:你想要将表A中的一行和表B中的两行组合成结果中的一行。

答案 2 :(得分:0)

您应该将查询翻译为标准SQL:

select a.ocd, b.DESCRIPT, a.CCD, b.DESCRIPT
from a
left join b on a.ocd = b.cd and a.ccd = b.cd