混合SQL内部联接和外部联接
我正在处理以下旧版Oracle SQL查询:混合SQL内部联接和外部联接,sql,oracle,join,left-join,Sql,Oracle,Join,Left Join,我正在处理以下旧版Oracle SQL查询: SELECT * FROM table1, table2, table3, table4 WHERE table1.job= table2.job(+) AND table1.event = table3.event(+) AND ((table2.column1= table4.key AND table4.resource_type = 'xxx') OR (table2.column2 = table4.key AND
SELECT *
FROM
table1, table2, table3, table4
WHERE
table1.job= table2.job(+)
AND table1.event = table3.event(+)
AND
((table2.column1= table4.key AND table4.resource_type = 'xxx')
OR (table2.column2 = table4.key AND table4.resource_type = 'yyy'))
我在表2中看到表有一个左外连接,在表3中看到表1有一个左外连接。但是现在最后一个条款做了什么
当我看维恩图时,我认为它返回了表1的所有内容,以及表2和表4的共同记录。那么这个查询是在执行两个数据集的某种联合吗?表2的
左连接实际上是内部连接。WHERE
子句正在撤消外部联接。所以我认为这是一个等价的查询:
SELECT *
FROM table1 JOIN
table2
ON table1.job = table2.job JOIN
table4
ON (table2.column1 = table4.key AND table4.resource_type = 'xxx') OR
(table2.column2 = table4.key AND table4.resource_type = 'yyy') LEFT JOIN
table3
ON table1.event = table3.event;
关于将外部联接转为内部联接的问题:
如果WHERE子句包含将列与
表B中有一个常数,则(+)运算符必须应用于
列,以便Oracle从表A中返回它已指定的行
为此列生成了空值。否则,Oracle只返回
简单联接的结果
表4包含(至少)两种资源类型{'xxx',yyy'}的记录。表2有第1列中资源类型“xxx”和第2列中资源类型“yyy”的相应ID。最后一个子句,即((表2.column1=table4.key和表4.resource_type='xxx')或(表2.column2=table4.key和表4.resource_type='yyy'))
实际上将表2上的“左联接”转换为联接,更具体地说,是像table1连接table2连接table4
,这样查询不一定包含table1
的所有记录
您可以这样想:假设table1
和table2
实际上是左连接的,这样(中间)结果包含table1
中的所有元组以及table2
的属性,其中table1.job
和table2.job
匹配,并为表2
属性设置空值,其中作业
不匹配。然后,一个where
-条件,如table2.column1=table4.key
将从(中间)结果中删除所有记录,其中table2.column1
与table4
中的任何记录都不匹配;因此请注意,table2.column1
中由左连接生成的null
-值将永远不会匹配,并将允许过滤掉这些记录。因此,如果table1.job
和table2.job
不匹配,则结果中不会有任何记录。但table2不是与常数比较,而是与另一个表中的列比较。@codecypher。所以没有(+)
,因此要求列具有非空值。因此,这将撤消外部联接。如果您在where子句中使用现代显式join
语法而不是过时的古老隐式联接,则更容易理解(此外:即使Oracle也建议不再使用专有的(+)
)请编辑您的问题并包括为上述查询生成的查询计划。谢谢