以下代码:
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
这对我来说没有意义。有人可以解释一下吗?
答案 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
解释为排序。