0

So if table A is:

no | username 
1  | admin
2  | chicken

And table B is:

id | no
a  | 1
b  | 3
c  | 4

Then, I do a NATURAL FULL OUTER JOIN as so:

SELECT no
FROM A NATURAL FULL OUTER JOIN
     B;

Then, what is the result? And is the result the same for all PostgreSQL implementations?

Because does the 'no' come from table A, or table B, it is ambiguous. But, NATURAL joins combine the 'no'. But what if one of the 'no' is ambiguous, i.e. A.no IS NOT NULL, but B.no IS NULL, which of the 'no' does it pick? And what if A.no and B.no are both NULL?

TL;DR: So the question is, WHAT is the value of the no in SELECT no: Is it the A.no or B.no, or is it the COLAESCE of them?

SELECT no
FROM A NATURAL FULL OUTER JOIN
     B;
4

1 回答 1

0

首先,不要natural用于连接。这是一个等待发生的错误。正如您在问题中所指出的,根据列的名称natural选择连接键。它不考虑类型。它甚至没有考虑明确声明的外键关系。

但是,特别隐蔽的问题是阅读查询的人看不到连接键。这使得调试查询或修改/增强它们变得更加困难。

所以,我的建议是using改用。

SELECT no
FROM A FULL OUTER JOIN
     B
     USING (no);

什么是full join回报?它返回两个表中的所有行,无论连接是否匹配。因为一次NULL比较总是失败,NULL在连接条件中不会匹配。

例如,以下查询返回 4 行而不是 2 行包含一个NULL值:

with x as (
      select NULL::int as id union all select NULL as id
     )
select id
from x full join
     x y
     using (id);

使用连接你会得到相同的结果natural,但我根本不使用那个构造。

我不是 100% 确定,但我很确定所有支持的 Postgres 版本full join都会以相同的方式工作。这种行为是专门从joins 和连接条件的 ANSI 定义派生的。

于 2016-12-04T15:29:28.443 回答