简体   繁体   English

当两个表都有 null 值时,左外连接不排除

[英]Left outer join doesn't exclude when both the table have null values

I have a requirement where I have to extract data exclusive to the left table.我有一个要求,我必须提取左表独有的数据。 I am using the left outer join for this.我为此使用左外连接。 But the output extract data that has a null value for the variable used in join condition in both the table which is not expected.但是 output 提取的数据具有 null 值,用于两个表中的连接条件中使用的变量,这是不期望的。 Below is the detailed condition,下面是详细情况,

TableA表A

id ID name姓名 subject主题
1 1 tom汤姆 math数学
2 2 jack杰克 null null

TableB表B

id ID name姓名 subject主题
3 3 john约翰 science科学
2 2 jack杰克 null null

Query询问

SELECT * 
  FROM TableA 
  LEFT JOIN TableB 
    ON a.id = b.id
   AND a.subject = b.subject
 WHERE b.id IS NULL
   AND b.subject IS NULL

Expected output预期 output

id ID name姓名 subject主题
1 1 tom汤姆 math数学

Actual output实际 output

id ID name姓名 subject主题
1 1 tom汤姆 math数学
2 2 jack杰克 null null

The problem is that, in your problem requirement, you seem to need to treat null as equal to (other) null .问题是,在您的问题要求中,您似乎需要将null视为等于(其他) null

This goes against the definition of null .这违背了null的定义。 But you can achieve your required result - in the join condition, change但是你可以达到你需要的结果——在加入条件下,改变

and a.subject = b.subject

to

and (a.subject = b.subject or (a.subject is null and b.subject is null))

In Oracle, you can do this more succintly:在 Oracle 中,您可以更简洁地执行此操作:

and decode (a.subject, b.subject, 1) = 1

because decode was defined intentionally to see two null as "equal".因为故意定义decode以将两个null视为“相等”。

You could do the same for the id column, if needed - but assuming it's supposed to be primary key in both tables, you shouldn't need it.如果需要,您可以对id列执行相同操作 - 但假设它应该是两个表中的主键,则不需要它。

EDIT The OP claims that the suggested use of decode produces the wrong result, while the explicit use of or (a.subject is null and b.subject is null) runs indefinitely on SQL Developer.编辑OP 声称建议使用decode会产生错误的结果,而显式使用or (a.subject is null and b.subject is null)在 SQL Developer 上无限期地运行。 So in this Edit I will show that the OP's claims are both wrong.因此,在此编辑中,我将表明 OP 的主张都是错误的。 (I ran everything on my copy of SQL Developer, so the IDE is not the issue.) (我在我的 SQL Developer 副本上运行了所有内容,因此 IDE 不是问题。)

What he is doing, we don't know, but both suggestions are 100% correct for the data provided and the query as given to us (after we add the table aliases, which are missing in the OP's query, and we select just the data from TableA ).他在做什么,我们不知道,但是对于所提供的数据和给我们的查询,这两个建议都是 100% 正确的(在我们添加了 OP 查询中缺少的表别名之后,我们 select 只是来自TableA的数据)。

Test data:测试数据:

create table tablea (id, name, subject) as
  select 1, 'tom' , 'math'    from dual union all
  select 2, 'jack', null      from dual
;

create table tableb (id, name, subject) as
  select 3, 'john', 'science' from dual union all
  select 2, 'jack', null      from dual
;

First query and result:第一个查询和结果:

SELECT a.* 
  FROM TableA a
  LEFT JOIN TableB b 
    ON a.id = b.id
   AND (a.subject = b.subject or (a.subject is null and b.subject is null))
 WHERE b.id IS NULL
   AND b.subject IS NULL
;

        ID NAME SUBJECT
---------- ---- -------
         1 tom  math

Second query and result:第二次查询和结果:

SELECT a.* 
  FROM TableA a
  LEFT JOIN TableB b 
    ON a.id = b.id
   AND decode(a.subject, b.subject, 1) = 1
 WHERE b.id IS NULL
   AND b.subject IS NULL
;

        ID NAME SUBJECT
---------- ---- -------
         1 tom  math

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM