2011-01-27 30 views
3

我有一個查詢需要返回一個標量值,如果該項目在表中多次引用一次。SQL Aggragates和Alias的

SELECT 
    COUNT(*) 
FROM 
    Items 
WHERE 
    FKID = 2003799 
GROUP BY 
    FKID 
HAVING 
    COUNT(*)>1 
ORDER BY 
    COUNT(*) 

爲什麼我不能指定aggragate一個別名,並在查詢的其餘部分引用別名,而不是重複aggragate功能?

喜歡的東西:

SELECT 
    COUNT(*) AS CountById 
FROM 
    Items 
WHERE 
    FKID = 2003799 
GROUP BY 
    FKID 
HAVING 
    CountById>1 
ORDER BY 
    CountById 

編輯 - 是否有其他語法,允許同樣的想法?

回答

0

因爲SELECT條款執行HAVING條款後,所以當引擎讀取HAVING條款,不知道的還什麼CountById手段。

+0

有道理,你知道是否有辦法完成同樣的想法?不得不重複這樣的混合功能,在我的嘴裏留下不好的味道。 – asawyer 2011-01-27 15:28:53

3

基本上,答案是... SELECT列表被解釋爲最後...這裏基本上是順序...參見http://databases.aspfaq.com/database/how-do-i-use-a-select-list-alias-in-the-where-or-group-by-clause.html

  1. 從FROM子句開始,從所有連接,聯合,交集以及其他任何表構造函數構建工作表。 AS選項允許您爲該工作表指定一個名稱,然後您必須爲該工作表的其餘部分使用該名稱。

  2. 轉到WHERE子句並刪除不通過條件的行;即不測試爲TRUE(拒絕UNKNOWN和FALSE)。 WHERE子句適用於FROM子句中的工作。

  3. 轉到可選的GROUP BY子句,製作組並將每個組縮小到一行,用原來的分組表替換原始工作表。分組表格的行必須是組特徵:(1)分組列(2)關於組的統計量(即集合函數)(3)函數或(4)由這三個項目組成的表達式。

  4. 轉到可選的HAVING子句並將其應用於分組工作表;如果沒有GROUP BY子句,則將整個表視爲一個組。

  5. 轉到SELECT子句並在列表中構造表達式。這意味着SELECT中的標量子查詢,函數調用和表達式在所有其他子句完成後完成。 AS運算符也可以給SELECT列表中的表達式命名。這些新名字一次性存在,但在WHERE子句執行後,出於這個原因,你不能在SELECT列表或WHERE cluase中使用它們。

  6. 嵌套查詢表達式遵循您期望從塊結構化語言(例如C,Pascal,Algol等)的通常範圍規則規則。即,最內層的查詢可以在包含它們的查詢中引用列和表。

1

原因與處理查詢的順序有關。在處理SELECT之前對GROUP BYHAVING進行評估,因此您的別名在此時未定義。另一方面,在SELECT之後處理ORDER BY,所以您的列別名在那裏有效。

Pinal Dave's Blog,評價的順序是:

  1. FROM
  2. ON
  3. OUTER
  4. WHERE
  5. GROUP BY
  6. CUBE | ROLLUP
  7. HAVING
  8. 選擇
  9. DISTINCT
  10. ORDER BY
  11. TOP
1

通常SELECT列表進行評估的聲明的最後一部分(即使它是第一部分!),所以沒有辦法在語句的其他子句中使用定義的別名。