2017-07-19 97 views
1

我正在使用PostgreSQL。我在这里读到的所有内容都表明,在查询中只使用单个列上的完全连接的情况下,连接表的顺序基本上无关紧要。为什么FULL JOIN顺序在这些查询中有所作为?

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

简化为三个表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); 

我想要/期望是难以表述,但基本上,一个我” d就像一个“完整”的全面兼并。除非不可避免,否则我不想在任何地方使用空字段。

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

当连接以其他顺序列出时,我确实得到了期望的结果(但我不确定可能会发生什么其他问题,因为未来的数据未知)。

+0

您是否期望输入表中可能存在NULL?做一些你的期望取决于超级键上的FULL JOIN(UNIQUE NOT NULL)?对表或连接是否有其他限制/限制?就输入而言,您期望/预期的结果究竟是什么?请给出示例输入,查询以及预期/期望和实际输出。 PS我怀疑没有这样的连接链是查询你想要的结果。我怀疑你需要某些联盟,而这在你的规范中扮演着重要的角色。尝试描述和给出你想要2和3表格的例子。 – philipxy

+0

[有没有什么经验法则可以从人类可读的描述中构建SQL查询?](https://stackoverflow.com/a/33952141/3404097) – philipxy

+0

你仍然不清楚你想要写的评论对GordonLinoff的回答。另外,“如果有多行......”,则表明,正如我在对您的问题的评论中所假设的那样,您的情况涉及某些假设*,但您没有给出*。事情比你想象的更复杂。如果你想回答你的问题,不管它是什么,请阅读[mcve]并采取行动,然后阅读我的评论并采取行动。至少,请对输入和预期输出进行检查。此外,评论不是澄清,请编辑您的问题。另请参阅我的回答。 – philipxy

回答

1

您的查询完全不同。

在第一个中,您正在使用单列id执行full joinb

第二,您正在使用两列执行full joinb

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

+0

这很有道理。但我没有完全得到的是我如何强制最后一张桌子的“ID”始终与第一张桌子相融合,就像第二张桌子的“ID”一样。 直觉上这就是我在'USING'关键字时期望'FULL JOIN'工作的原因,因为只有一个'id'列被返回。 – Lenoxus

+1

@Lenoxus“永远融合”是什么意思? PS定义,而不是直觉。 – philipxy

+0

我明白为什么不清楚。我希望结果表具有尽可能少的行数。 因此:除非值真正无法确定,否则不包含空值。如果存在多行,例如具有相同的id和id_x值,则这必须是因为表b和c都具有包含这些值的行。 结果表应该反映这些表格数据中的每个关系/重叠,但不能超过这些。 – Lenoxus

0

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

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

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

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

你的问题并没有明确说明你正在假设什么样的输入条件或你正在寻找什么输出条件。

相关问题