繁体   English   中英

INNER JOIN的不明确的列名SQL错误:为什么?

[英]Ambiguous column name SQL error with INNER JOIN: Why?

以下代码将用于从两个表中选择数据:

SELECT t1.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo=t2.foo

我可以这么容易写

SELECT t2.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo=t2.foo

t1.foot2.foo :一个或六个中的六个。 为什么不只是foo

我一直在想,为什么SQL服务器只是在没有指定一个表或另一个表的情况下自动返回数据,因为选择完全是任意的(据我所知)。

我可以编写一个你需要指定表格的场景,例如

SELECT t1.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE t2 ON t1.foo+=t2.foo

但是,根据我的经验,这种情况远非常态。

任何人都可以告诉我为什么语言的设计,以便我必须在我的代码中做出这个看似随意的决定?

因为MS SQL中的相等并不一定意味着它们在您想要的值中相等。 考虑foo的以下2个值:“Bar”,“baR”。 Sql会认为它们在连接方面是相同的,因为比较中固有的不区分大小写,但是你要求哪一个? SQL Server不知道,也无法猜测。 你必须明确告诉它。

编辑:正如@Lukas Eder提出的那样,并非所有SQL实现都使用不区分大小写的比较。 我知道MS SQL使用不区分大小写,我的答案正是考虑到这个概念。

你的推理并不完全正确。 虽然t1.foo = t2.foo可能成立,但这并不意味着它们是相同的。 一些例子:

  • 一个可能是VARCHAR(1)另一个VARCHAR(2)
  • 一个可能是VARCHAR(1)另一个NUMBER(1)
  • t1可以是一个简单的表,而t2是一个视图(或嵌套的选择),它对foo的值进行超复杂的计算。 在某些RDBMS中, foo的投影成本可能不同。

还有其他几十个原因,为什么写foo会很尴尬

如果您确定列表示相同的内容,则可以使用USING子句加入。

SELECT foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 USING (foo);

否则,无法保证t1.foo与t2.foo相同

在这种情况下,您有一个INNER JOIN,因此很明显该决定是任意的。 但是在很多情况下,即使你加入FOO,2也不一样。

EX:在LEFT JOIN的情况下,如果你有类似ON t1.foo = t2.foo + / - / whater的话

引擎需要您的输入才能知道从哪里获取数据。

你需要做出这个决定的原因是它不是任意的。 系统不知道哪个表包含您想要的数据。 你需要指定它。 当系统设计执行计划时,它不会确定哪些列在两个表中包含相同的数据。 就它而言,这两列可能有不同的数据。 它不打算推断,因为你说这些列是相同的,当没有指定一列时它可以显示任一列。

在那种特殊情况下, t1.foot2.foo是相同的东西,但引擎没有针对它进行优化(如果是的话会引起混淆)。 如果你的加入做了一些他们可能不一样的事情,比如这样呢?

SELECT t2.foo, t2.bar FROM TABLE1 t1 INNER JOIN TABLE2 t2 ON t1.foo<t2.foo

由于我们使用< ,foo对t1和t2可能是非常不同的东西。 在这种情况下,引擎无法“猜测”。

仅仅因为这些体验在您的体验中“远非常规”,引擎必须允许它,否则会使某些类型的查询极难编写。

SQL没有这样做,因为它根本无法解决歧义。 (但是你注意到它们是等价的。)

对于应用程序生命周期,最好自己解决它们,因为如果列更改名称或连接类型发生更改,则代码不太可能被破坏,并且您的意图更明显。 但是我确信这些好处不是故意的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM