为什么这种语法无效?

时间:2012-11-26 19:27:59

标签: sql sql-server sql-server-2005

以下代码:

SELECT JaguarStartupTime, CPU, AmountOfRam, UpdatedOn, *
FROM dbo.MachineConfiguration
WHERE ServerName = 'WashingtonDC01'
AND UpdatedOn > '11/21/2012'
ORDER BY JaguarStartupTime DESC

导致错误:Ambiguous column name 'JaguarStartupTime'

但是,删除ORDER BY会使其正常工作。另外,在ORDER BY子句前加上表格,如下所示,也可以使它起作用:

SELECT JaguarStartupTime, CPU, AmountOfRam, UpdatedOn, *
FROM dbo.MachineConfiguration
WHERE ServerName = 'WashingtonDC01'
AND UpdatedOn > '11/21/2012'
ORDER BY dbo.MachineConfiguration.JaguarStartupTime DESC

这对我来说没有意义。有人可以解释一下吗?

2 个答案:

答案 0 :(得分:8)

因为查询在SELECT子句中包含*(所有列),其中还包括JaguarStartupTime列。

在Layman的术语中: 因此,在检索结果时,列会显示两次,然后当服务器尝试应用排序顺序时,它不确定您指的是哪一列。

就个人而言,我改变查询以消除在查询中使用*,即使这意味着列出一长列列名。它是best practice,它可以避免这个问题。


至于为什么它在作为前缀时起作用,我在MSDN documentation

中找到了它
  

在SQL Server中,解析了限定列名和别名   FROM子句中列出的列。如果order_by_expression不是   限定,该值必须在列出的所有列中唯一   SELECT语句。

这只是数据库引擎将SQL语句转换为执行计划的基础机制的一部分。

答案 1 :(得分:1)

我同意在你的问题ORDER BY JaguarStartupTime中的情况并不是很模糊,因为两个预测列事实上都指的是相同的基础列。

但在一般情况下,并不能保证这是真的。 As discussed in the response to this connect item。例如,在下面的查询中,使用哪一个显然是模糊的。

SELECT JaguarStartupTime,
       CPU AS JaguarStartupTime
FROM   dbo.MachineConfiguration
ORDER  BY JaguarStartupTime DESC 

出于语法验证的目的,SQL Server不会对列名进行任何分析,以确定它们是否真的不明确。按some_name排序时,some_name必须是唯一的。这是按the ANSI spec

  

如果<sort specification>包含<column name>,则T                 应该只包含一列<column name>和。{                 <sort specification>标识该列。

使用表名限定列名可确保SQL Server按源列名而不是投影列名进行排序,以便允许它。

SELECT name, name 
FROM master..spt_values v1
ORDER BY v1.name

此外,还允许以下查询。

select name, name 
FROM master..spt_values v1
ORDER BY name + ''

这不明确的原因是因为ORDER BY子句中的列别名只能由它们自己使用而不能在表达式中使用,所以在上面的查询中name不能被解释为别名并且必须按v1.name解释为排序。