【问题标题】:Why is the column reference ambiguous in INNER JOIN, but not in NATURAL JOIN?为什么 INNER JOIN 中的列引用不明确,而 NATURAL JOIN 中却没有?
【发布时间】:2016-08-15 14:50:23
【问题描述】:

我想知道为什么 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 相同。

【问题讨论】:

  • JOIN 返回两个表的 C 列。自然连接返回一个 C 列(结果相同),“无表”。
  • @Patrick,好吧,我写了评论,而不是答案……无论如何,答案就在那里。常规的JOIN ... ON 返回两列 C,(A.C 和 B.C),您需要指定您想要的列。一个NATURAL JOIN,还有一个JOIN ... USING (C),只返回一列C。那么它就不能模棱两可了!
  • 那么你有答案了吗?

标签: sql postgresql join


【解决方案1】:

NATURAL JOIN 中,字段按列名连接,因此如果行匹配,则定义为A.c = B.c。使用 USING 短语时也是如此:匹配仅在普通的 vanilla 列名上进行。两者的区别在于,第一个选项会连接所有匹配的列名,而第二个选项则必须指定相似的列名,因此您可以选择将哪些列名包含在连接中。

在使用ON 短语连接的情况下,即使列名相同,这种行值的相等也不一定是这种情况。考虑这种情况:

SELECT c
FROM A
JOIN B ON A.c = 6 * B.c;

换句话说,即使两个关系都有一个同名列,两个关系的行中的那些列的值也不必相同才能进行匹配,因为任何类型的表达式都可能涉及到一行或两行的值。因此,为什么您需要明确说明要从中选择行值的关系。

【讨论】:

  • “仅在普通的香草列名上进行匹配” - 当然类型也必须相同(或“兼容”)?
  • “明确说明要从中选择行值的关系”-我认为您的意思不是“关系”。我认为这应该是,“明确说明c 与哪个范围变量(AB)相关。”
【解决方案2】:

如果您想在显式连接中使用明确的列引用,请使用using

select c 
from 
    a 
    inner join
    b using (c)

USING (a, b, ...) 形式的子句是 ON left_table.a = right_table.a AND left_table.b = right_table.b ... 的简写。此外,USING 意味着每个子句中只有一个连接输出中将包含一对等效列,而不是两者。

【讨论】:

  • 这不能回答问题。
【解决方案3】:

第二个查询的连接结果中有一个名为“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:

NATURALUSING 列表的简写,它提到了两个表中同名的所有列。

还有:

USING ( a, b, ... ) 形式的子句是ON left_table.a = right_table.a AND left_table.b = right_table.b .... 的简写 此外,USING 暗示 每对等效列中只有一个 将包含在连接输出中,而不是两者。

我的大胆强调。

【讨论】:

    猜你喜欢
    • 2019-09-30
    • 2010-10-08
    • 2011-09-25
    • 2015-03-03
    • 1970-01-01
    • 2019-04-05
    • 2020-01-09
    • 2010-09-07
    相关资源
    最近更新 更多