我正在使用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而不是空。相反,其中一个示例查询返回半冗余结果,其中一行具有 name_a但没有 id,另一行具有 id 但没有 name_a,而不是单个合并行。
当联接按其他顺序列出时,我确实得到了所需的结果(但我不确定还会出现什么其他问题,因为未来的数据是未知的(。
您的查询是不同的。
首先,您将使用单列id
执行b
full join
。
在第二部分中,您将使用两列执行b
full join
。
尽管这两个查询在某些情况下可以返回相同的结果,但没有理由认为结果具有可比性。
参数顺序在外连接中很重要,除了完全自然连接是对称的。它们返回内部连接(ON、USING 或 NATURAL(的作用,以及由 NULL 扩展的左侧(左连接(、右表(右连接(或两者(完全连接(表中不匹配的行。
USING 返回 INNER JOIN 行中每个指定列的单个共享值;在 NULL 扩展行中,另一个公用列可以在一个表的版本中包含 NULL,而在另一个表的版本中具有值。
加入顺序也很重要。甚至完全自然连接也不是关联的,因为对于多个表,每对表(操作数是原始表或连接结果(可以具有一组唯一的公共列,即一般 (A ⟗ B( ⟗ C ≠ A ⟗ (B ⟗ C(。
在很多特殊情况下,某些额外的身份仍然存在。例如,使用所有常见列名的完全连接和同名列的外连接相等是对称的。某些情况涉及 CK(候选键(、FK(外键(和其他参数约束。
您的问题没有明确说明您假设的输入条件或您正在寻找的输出条件。