我想知道为什么PostgreSQL会在此声明中产生模糊的引用错误:
SELECT c from A JOIN B ON A.c = B.c; -- ERROR: column reference is ambiguous
但不是这样:
SELECT c FROM A NATURAL JOIN B; -- OK
在这两种情况下,A.c
必须与B.c
相同。
答案 0 :(得分:2)
如果要在显式联接中使用明确的列引用,请使用using
:
select c
from
a
inner join
b using (c)
USING(a,b,...)形式的一个子句是ON left_table.a = right_table.a和left_table.b = right_table.b ....的简写。另外,USING意味着每个只有一个一对等效列将包含在连接输出中,而不是两者。
答案 1 :(得分:0)
在NATURAL JOIN
中,字段按列名称连接,因此如果行匹配,则A.c = B.c
按定义匹配。使用USING
短语时也是如此:匹配仅在普通的香草列名称上进行。两者之间的区别在于,使用第一个选项连接所有匹配的列名称,而使用第二个选项时,您必须指定相似的列名称,因此您可以选择在连接中包含哪些列。
在使用ON
短语加入的情况下,即使列名相同,行值的相等也不一定如此。请考虑以下情况:
SELECT c
FROM A
JOIN B ON A.c = 6 * B.c;
换句话说,即使两个关系都具有相同名称的列,两个关系中的行中这些列的值也不必相同以进行匹配,因为任何类型的表达式都可能涉及到一行或两行的值。因此,为什么需要明确要从哪个关系中选择行值。
答案 2 :(得分:0)
在第二个查询的结果中, 一个 列名为“c”。
第一个查询中的联接结果中有 两个 列名为“c”。
因此,列名“c”在您的第一个示例中不明确,但在第二个示例中则不然。错误消息很明确。这就是它的程度。名为“c”的两列的值是否相同无关紧要。引用不明确,因此出现错误消息。
SQL允许多个列在结果集中具有相同的名称。但引用必须是明确的。表格限定将使其明确无误:
SELECT a.c FROM a JOIN b ON a.c = b.c;
或者:
SELECT b.c FROM a JOIN b ON a.c = b.c;
为什么 在第二个查询中只有一个名为“c”的列? Quoting the manual:
NATURAL
是USING
列表的简写,提及两个表中具有相同名称的所有列。
和
USING ( a, b, ... )
形式的子句是ON left_table.a = right_table.a AND left_table.b = right_table.b ....
的简写 此外,USING
暗示每对等效列中只有一个 将包含在连接输出中,而不是两者。
大胆强调我的。