Sql 为什么两个表之间的完全外部联接的结果中有空值?

Sql 为什么两个表之间的完全外部联接的结果中有空值?,sql,postgresql,join,null,full-outer-join,Sql,Postgresql,Join,Null,Full Outer Join,我试图从两个表中获取唯一的值,这两个表都只有一个名为domain的列 DDL: DML: 有几种方法可以做到这一点,我决定使用完全外部联接 select case when a.domain is null then b.domain when b.domain is null then a.domain end as unique_domains from domains_1 as a full outer join domains_2 as b on a

我试图从两个表中获取唯一的值,这两个表都只有一个名为domain的列

DDL:

DML:

有几种方法可以做到这一点,我决定使用完全外部联接

select case when a.domain is null then b.domain
            when b.domain is null then a.domain
       end as unique_domains
from domains_1 as a full outer join domains_2 as b on a.domain = b.domain;
令我惊讶的是,除了唯一的域之外,结果中还有
null

我可以再添加一层
select
以排除空值,如下所示:

select * from
(select case when a.domain is null then b.domain
            when b.domain is null then a.domain
       end as unique_domains
from domains_1 as a full outer join domains_2 as b on a.domain = b.domain) t
where unique_domains is not null;
首先,这个
null
怎么会出现在结果中?
是否有更好的方法从结果中删除
null

您的
CASE
表达式没有
ELSE
,因此它默认为null:

case when a.domain is null then b.domain
     when b.domain is null then a.domain
     ELSE NULL -- implicitly
end as unique_domains
值“example_2.com”具有匹配项,因此a.domain和b.domain都等于“example_2.com”,且不为null。因此,应用了当不匹配时的
,以及当
否则为空时的

至于“更好的方法”:我可能会使用

select coalesce(a.domain, b.domain) as domain
from domains_1 as a full outer join domains_2 as b on a.domain = b.domain
where a.domain is null or b.domain is null;

SELECT
列表中的
CASE
表达式无法删除行(就像您希望的那样)。这必须发生在
JOIN
WHERE
子句中

由于列名可以方便地对齐,因此可以使用join子句中的
关键字来简化作业

要获取“唯一域”(包括示例中的“example_2.com”),请执行以下操作:

选择域
来自域1
使用(域)完全连接域2;
要分别获取其他表中不匹配的域(示例中的“example_2.com”除外):

选择域
来自域_1 a
使用(域)完全连接域\u 2 b
其中a.domain为NULL或b.domain为NULL;
小提琴

[…]
使用
意味着联接输出中只包含每对等效列中的一个,而不是两个

但您仍然可以通过表限定每个源列来引用它,如所示

有多种其他查询技术可以消除另一个表中匹配的行:

值得注意的是,除非另一个表中存在匹配项,否则上述两个查询都不会删除每个表中的重复项

第二个查询的奇特等效项,但每个表中都没有可能的重复项:

(表域_1,表域_2除外)
联合所有
(表域_2,表域_1除外);
此变体仅为另一个表中的每个匹配消除一个重复项,然后删除结果中剩余的重复项。微妙的不同,但:

(表域\u 1,所有表域\u 2除外)
联合
(表域_2,所有表域_1除外);
关于简短语法:


是否有任何方法可以从结果中排除此
null
?这是我的最终目标。感谢您指出
else
案例。您似乎希望显示只存在于其中一个表中的域,而不是同时存在于两个表中的域。这就是我的查询所做的。你的为匹配项创建空值,我的排除匹配项。明白了。我已经接受了你的回答。谢谢,不用了。在这一部分,我非常清楚外部连接,但我的问题是如何找到更好的方法来排除对应于匹配情况的null。为什么要出现它?如果你不说为什么,那么你只是在要求对你所使用的语言的各个部分进行另一种定义,而不让我们知道你不懂什么。还有什么是第一个子表达式,它不返回您期望的结果(为什么)?此外,“两个表中的唯一值”也很模糊。(但在你继续询问你的总体目标之前,先找出你误解了什么。)@TimothyG。这不是完整外部联接返回的正确定义。请注意,你所引用的令人遗憾的高投票率被接受的答案,除了极端贫困之外,甚至不能解决一般情况。(该页上唯一清晰完整的定义是我的。)(完全连接返回行上的内部连接,并将所有不匹配的左、右表行以null扩展。)
case when a.domain is null then b.domain
     when b.domain is null then a.domain
     ELSE NULL -- implicitly
end as unique_domains
select coalesce(a.domain, b.domain) as domain
from domains_1 as a full outer join domains_2 as b on a.domain = b.domain
where a.domain is null or b.domain is null;