Oracle左外部联接在联接vs WHERE条件中为null(示例)
我无法理解Oracle返回这种奇怪结果的原因。 我认为代码真的很清楚 我预料 无条件=(在外部联接条件中不为null)+(在外部联接条件中为null) 因为我将外部联接右表列中的IS NULL/IS NOT NULL解释为EXISTS/NOT EXISTS条件 为什么我错了Oracle左外部联接在联接vs WHERE条件中为null(示例),oracle,outer-join,Oracle,Outer Join,我无法理解Oracle返回这种奇怪结果的原因。 我认为代码真的很清楚 我预料 无条件=(在外部联接条件中不为null)+(在外部联接条件中为null) 因为我将外部联接右表列中的IS NULL/IS NOT NULL解释为EXISTS/NOT EXISTS条件 为什么我错了 DESCRIPTION COUNT(1) ---------------------------------- ---------- No condition
DESCRIPTION COUNT(1)
---------------------------------- ----------
No condition 6403
is NOT null in OUTER JOIN cond 6403
is not null in where cond 6401
is null in OUTER JOIN cond 6247
is null in where cond 2
proof flh_id_messaggio is not null 0
proof flh_stato is not null 0
SELECT 'is null in OUTER JOIN cond ' description, count(1)
FROM netatemp.TMP_BACKLOG_NOBILLING2013 t
LEFT OUTER JOIN
eni_flussi_hub c ON
c.flh_id_messaggio = t.flh_id_messaggio
AND c.flh_stato is null
WHERE 1 = 1
And t.flh_stato = 'PA'
AND t.OWNER = 'ETL'
UNION
SELECT 'is NOT null in OUTER JOIN cond ' description, count(1)
FROM netatemp.TMP_BACKLOG_NOBILLING2013 t
LEFT OUTER JOIN
eni_flussi_hub c ON
c.flh_id_messaggio = t.flh_id_messaggio
AND c.flh_stato is not null
WHERE 1 = 1
And t.flh_stato = 'PA'
AND t.OWNER = 'ETL'
UNION
SELECT 'is null in where cond ' description, count(1)
FROM netatemp.TMP_BACKLOG_NOBILLING2013 t
LEFT OUTER JOIN
eni_flussi_hub c ON
c.flh_id_messaggio = t.flh_id_messaggio
WHERE 1 = 1
And t.flh_stato = 'PA'
AND t.OWNER = 'ETL'
AND c.flh_stato is null
UNION
SELECT 'is not null in where cond ' description, count(1)
FROM netatemp.TMP_BACKLOG_NOBILLING2013 t
LEFT OUTER JOIN
eni_flussi_hub c ON
c.flh_id_messaggio = t.flh_id_messaggio
WHERE 1 = 1
And t.flh_stato = 'PA'
AND t.OWNER = 'ETL'
AND c.flh_stato is not null
UNION
SELECT 'No condition' description, count(1)
FROM netatemp.TMP_BACKLOG_NOBILLING2013 t
LEFT OUTER JOIN
eni_flussi_hub c ON
c.flh_id_messaggio = t.flh_id_messaggio
WHERE 1 = 1
And t.flh_stato = 'PA'
AND t.OWNER = 'ETL'
UNION select 'proof flh_stato is not null' description, count(1)
from eni_flussi_hub
where flh_stato is null
UNION select 'proof flh_id_messaggio is not null' description, count(1)
from eni_flussi_hub
where flh_id_messaggio is null
存在
/不存在
等效查询是通过将NULL
条件放置在WHERE
子句中而不是外部联接
子句中获得的。顺便说一下,这是我们从您的结果中观察到的:
No condition 6403
is not null in where cond 6401
is null in where cond 2
主表中的2行在联接表中没有相应的ID
当您在
外部联接
子句中放置条件时,您告诉Oracle将外部联接
您的主表从联接表中转到一个行子集
由于c.flh_stato
从不为空,因此该条件是冗余的,我们得到的结果与无条件查询相同:
No condition 6403
is NOT null in OUTER JOIN cond 6403
如果join子句中的条件c.flh_stato为NULL
,我们将主表连接到一个空结果集,因此主表的每行得到一行(我们推断主表有6247行具有此条件):
真的很高兴知道。即使我觉得甲骨文很奇怪。。。为什么允许在联接条件中预筛选表。。真奇怪。。我认为在连接条件中只使用连接条件,可能使用EXIST/NOT EXIST等效项。。不是预过滤器…@Gik25我不确定这是Oracle特有的。这似乎是SQLSynthax的一个直接应用程序。请参见中的这些行为类似的示例。通常情况下,使用
NOT IN
或NOT EXISTS
的反连接更容易理解,并且在Oracle中具有相同的优化器选项(不过要注意空值)。
is null in OUTER JOIN cond 6247