为什么FULL JOIN命令会对这些查询产生影响?

时间:2017-07-19 16:40:50

标签: sql postgresql null outer-join associativity

我正在使用PostgreSQL。我在这里阅读的所有内容都表明,在一个查询中,只使用单个列上的完整连接,加入的表的顺序基本上没有关系。

我的直觉说这也应该用于多列,只要在可能的情况下在查询中列出每个公共列(即,两个连接表都具有共同列的位置)。但这不是 的情况,我试图找出原因。

简化为三个表a,b和c。

Columns in table a: id, name_a
Columns in table b: id, id_x
Columns in table c: id, id_x

此查询:

SELECT *
FROM a
    FULL JOIN b USING(id)
    FULL JOIN c USING(id, id_x);

返回的行数与此不同:

SELECT *
FROM a
    FULL JOIN c USING(id)
    FULL JOIN b USING(id, id_x);

我想要/期望的内容很难说清楚,但基本上,我喜欢"完成"完全合并。我希望在任何地方都没有空字段,除非这是不可避免的。

例如,每当有一个非空的id时,我希望总是的相应名称列具有name_a而不是null。相反,其中一个示例查询返回半冗余结果,其中一行具有name_a但没有id,另一行具有id但没有name_a,而不是单个合并行。

当连接以其他顺序列出时,我确实得到了所需的结果(但我不确定可能会出现哪些其他问题,因为未来的数据未知)。

2 个答案:

答案 0 :(得分:1)

您的查询不同。

首先,您使用一列full join进行bid

在第二步中,您使用两列进行full joinb

虽然在某些情况下这两个查询可能会返回相同的结果,但没有理由认为结果具有可比性。

答案 1 :(得分:0)

参数顺序在OUTER JOIN中很重要,除了FULL NATURAL JOIN是对称的。它们返回INNER JOIN(ON,USING或NATURAL)所执行的操作,但也返回由NULL扩展的左侧(LEFT JOIN),右侧(RIGHT JOIN)或两个(FULL JOIN)表的不匹配行。

USING返回INNER JOIN行中每个指定列的单个共享值;在NULL扩展行中,另一个公共列可以在一个表的版本中具有NULL,在另一个表中具有值。

加入订单也很重要。甚至FULL NATURAL JOIN也不是关联的,因为对于多个表,每对表(操作数是原始或连接结果)可以有一组唯一的公共列,即一般(A⟗B)⟗C≠A⟗(B ⟗C)。

有很多特殊情况需要某些额外的身份。例如FULL JOIN使用所有公共列名称和OUTER JOIN ON相同命名列的相等性是对称的。有些案例涉及CK(候选键),FK(外键)和其他参数约束。

您的问题并未明确说明您正在考虑的输入条件或您正在寻求的输出条件。