Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
混合SQL内部联接和外部联接_Sql_Oracle_Join_Left Join - Fatal编程技术网

混合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

我正在处理以下旧版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 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也建议不再使用专有的
(+)
)请编辑您的问题并包括为上述查询生成的查询计划。谢谢