Sql Oracle在同一列上联接两个表

Sql Oracle在同一列上联接两个表,sql,oracle,join,Sql,Oracle,Join,有人能解释一下为什么下面的查询在description字段中返回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 不正确的查询:尽管

有人能解释一下为什么下面的查询在description字段中返回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(+);

您应该将查询转换为标准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

您应该将查询转换为标准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

您需要查找两次值,因为您有两个代码。这需要两个联接,如果存在不匹配的可能性,则应为
左联接
s:

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将来也可能不支持它。

您需要查找两次值,因为您有两个代码。这需要两个联接,如果存在不匹配的可能性,则应为
左联接
s:

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将来也可能不支持它。

从您所谓的“正确查询”中,您似乎希望从表A中选择每一行,然后为该行中的每一个值选择表B中某一行中的对应值。在第一次查询中,在联接表A和表B的情况下,联接条件要求表A行中的两个值在表B的同一行中匹配。显然,这不符合您的规范。如果要将表A中的一行与表B中的两行(通常不同)进行匹配,则需要将表A与表B连接两次,就像在正确的查询中一样

联接两个表时,将检查第一个表中的一行和第二个表中的一行的所有组合,以查看是否满足联接条件。联接三个表时,将根据联接条件检查三个表中每个表中一行的所有组合。这就是为什么在联接中需要表B两次的原因:您希望将表A中的一行和表B中的两行合并为结果中的一行。

从您所谓的“正确查询”中,您似乎希望从表A中选择每一行,然后针对该行中的每一个值,选择表B中一行中的对应值。在第一次查询中,在联接表A和表B的情况下,联接条件要求表A行中的两个值在表B的同一行中匹配。显然,这不符合您的规范。如果要将表A中的一行与表B中的两行(通常不同)进行匹配,则需要将表A与表B连接两次,就像在正确的查询中一样


联接两个表时,将检查第一个表中的一行和第二个表中的一行的所有组合,以查看是否满足联接条件。联接三个表时,将根据联接条件检查三个表中每个表中一行的所有组合。这就是为什么在联接中需要表B两次:要将表A中的一行和表B中的两行合并为结果中的一行。

使用适当的
左联接
运算符。甚至Oracle也建议停止使用
(+)
谢谢。你能为我贴出的问题提供查询和解释吗?你能检查并更正你的“正确查询”吗。在第二个查询中,您似乎正在连接三个表!!您的查询的预期输出是什么?我很难理解你打算做什么。@pratik garg:我已经修改了查询。很抱歉出现任何混淆。请使用正确的
左联接
运算符。甚至Oracle也建议停止使用
(+)
谢谢。你能为我贴出的问题提供查询和解释吗?你能检查并更正你的“正确查询”吗。在第二个查询中,您似乎正在连接三个表!!您的查询的预期输出是什么?我很难理解你打算做什么。@pratik garg:我已经修改了查询。很抱歉造成混淆。我已经运行了您提供的查询,它将导致描述字段的值为空。这与我提供的错误查询完全相同。创建这两个简单的表并运行您提供的查询。如果您不希望为空,请使用内部联接而不是左联接:
从a.ocd=b.cd和a.CCD=b.cd上的内部联接中选择a.ocd、b.DESCRIPT、a.CCD、b.DESCRIPT
我已运行您提供的查询,它将为描述字段生成空值。这与我提供的错误查询完全相同。创建这两个简单的表并运行您提供的查询。如果您不希望为空,请使用内部联接而不是左联接:
选择a.ocd、b.DESCRIPT、a.CCD、,b.DESCRIPT从a.ocd=b.cd和a.ccd=b.cd上的内部联接b进行描述
能否请您详细解释查询内部发生的情况?我提供的查询不正确,为什么它会返回描述字段的所有空值?能否请您详细解释查询内部发生的情况我提供的查询不正确,为什么它会返回描述字段的所有空值。