有人可以向我解释为什么下面的查询在描述字段中返回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(+);
答案 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