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

时间:2011-05-11 14:55:59

标签: sql sql-server inner-join

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

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

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

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

7 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:4)

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

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

还有其他几十个原因,为什么只写foo

会很暧昧

答案 2 :(得分:3)

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

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

否则无法保证t1.foo与t2.foo

相同

答案 3 :(得分:1)

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

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

的内容

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

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

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

答案 6 :(得分:0)

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

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

相关问题