【问题标题】:Why does SQL complain that a reference to a join key is ambiguous?为什么 SQL 抱怨对连接键的引用不明确?
【发布时间】:2021-07-15 18:17:23
【问题描述】:

为什么 Vertica 在以下代码中返回 zip3 不明确的错误?由于它是作为左连接的键,所以两个表必须相等。

SELECT zip, zip3, city, zip3_name
FROM zip_codes
LEFT JOIN zip3_codes
USING (zip3);

这会产生以下错误:

Query 1 ERROR: ERROR:  Column reference "zip3" is ambiguous
DETAIL:  Reference "zip3" could refer to either "public.zip_codes.zip3" or "public.zip3_codes.zip3"

我可以通过选择 zip.zip3zip3.zip3COALESCE(zip.zip3, zip3.zip3) 来解决此问题,但我很好奇为什么需要这样做。

【问题讨论】:

  • @steveo314 当然它在两个表中 - 否则,USING 将不起作用。
  • 您可以尝试使用* 作为投影中的列列表吗?
  • Postgres 不会产生此错误,因此您应该删除标签:dbfiddle.uk/…
  • PostgreSQL 和 Vertica 是不同的东西。您的问题如何涉及 PostgreSQL?

标签: sql vertica


【解决方案1】:

虽然乍一看似乎列必须始终相同,但事实并非如此。 JOIN 实际上是一个LEFT JOIN,它返回第一个表中的所有行以及第二个表中所有可能的匹配项,当没有匹配项时给出NULLs。

来自zip_codes 的不匹配记录将导致zip.zip3zip3.zip3 中的值不同,恰好第一个给出一个值,第二个是NULL,因此在这种特殊情况下交换它们并不真正等同,您需要确定您需要哪个表中的哪些列,并消除其表名的歧义。

此外,即使不是这种情况,错误仍然会弹出。如果我们将您的 LEFT JOIN 更改为 INNER JOIN,您的假设将是正确的,并且列将始终具有相同的值,但您仍然会得到相同的错误。

原因是 SQL 分析器不够聪明,无法实现值始终相同。按照标准,如果您的查询引用来自不同表的同名列,您必须指定它来自哪个表。没有进一步尝试解决歧义。

【讨论】:

  • 出于好奇,Vertica 如何使用 SELECT *(根据 @Sergey Kalinichenko 正确运行)而不是 SELECT zip, zip3, ... 来解决歧义?
  • @prototype SELECT * 从每个表中选择每一列,因此没有歧义。您将看到两个zip3,每个表中都有一个。歧义来自于代码无法分辨出您在说哪一个。但使用* 很简单:两者兼而有之。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2020-08-12
  • 2016-02-27
  • 1970-01-01
  • 2016-03-30
  • 2013-03-28
  • 1970-01-01
相关资源
最近更新 更多