2012-11-26 56 views
3

以下代碼:爲什麼這個語法無效?

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 

這從來沒有對我有意義。有人可以解釋嗎?

回答

8

因爲查詢包括SELECT子句中的*(所有列),其中還包括JaguarStartupTime列。

在Layman的條款中: 因此,在檢索結果時,該列顯示兩次,然後當服務器嘗試應用排序順序時,不確定您所指的是哪一列。

就個人而言,我會更改查詢以消除在查詢中使用*,即使這意味着要列出一長列列名稱。這是best practice,它會避免這個問題。


至於爲什麼前綴時,它的工作原理,我發現這個在MSDN documentation

In SQL Server, qualified column names and aliases are resolved to columns listed in the FROM clause. If order_by_expression is not qualified, the value must be unique among all columns listed in the SELECT statement.

這是一個簡單的數據庫引擎對翻譯SQL語句轉換爲執行計劃基本機制的一部分。

+0

唉!你快了! ;-)刪除了我的答案和+1。 –

+1

服務器知道它是同一列。例如,如果我將JaguarStartupTime添加到WHERE子句中,則儘管存在兩個相同的列,但它很樂意過濾它。 – AngryHacker

+1

@AngryHacker - 'WHERE'在'FROM'之後但在'SELECT'之前處理。 'ORDER'出現在'SELECT'後面。 (所有這些命令都是「好像」 - 只要結果相同,引擎可以自由地重新排序這些操作) –

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

If a <sort specification> contains a <column name> , then T shall contain exactly one column with that <column name> and the <sort specification> identifies that column.

排位賽列名和表名,以確保您的源列的名稱,而不是預計的列名排序,因此允許它的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排序。