2011-05-27 41 views
6

我有一個查詢瞭解Oracle別名 - 除非包含在第二個查詢中,否則爲什麼在查詢中不能識別別名?


SELECT COUNT(*) AS "CNT", 
     imei 
FROM devices 

它執行就好了。我想用WHERE語句進一步限制查詢。的(力所能及)合理的下一步是修改從動地查詢:


SELECT COUNT(*) AS "CNT", 
     imei 
FROM devices 
WHERE CNT > 1 

然而,這導致一個錯誤消息ORA-00904:「CNT」:無效的標識符。出於某種原因,在另一個查詢包裹查詢生成所需的結果:


SELECT * 
FROM (SELECT COUNT(*) AS "CNT", 
       imei 
     FROM devices 
     GROUP BY imei) 
WHERE CNT > 1 

爲什麼甲骨文無法識別別名「CNT」,在第二個查詢?

+1

作爲旁註:此查詢(帶聚合)用HAVING語句寫得更好:「select count((*))cnt,imei from imei count((*))> 1」 – 2011-05-27 15:06:59

回答

8

簡單的答案是AS子句定義了在結果中調用列的位置,這與查詢本身的範圍不同。

在您的例子,使用HAVING子句將最好的工作:

SELECT COUNT(*) AS "CNT", 
     imei 
FROM devices 
GROUP BY imei 
HAVING COUNT(*) > 1 
+1

在OP的問題中,這不僅僅是HAVING最好的工作,而是HAVING纔是答案。你不能將一個where子句應用到count(*)這樣的聚合中,這就是HAVING子句存在的原因。另外,按照標準的SQL處理順序,WHERE發生在SELECT之前,因此在應用WHERE子句時,別名CNT甚至不存在。 From,Where,By By,Having,Select Order By http://www.bennadel.com/blog/70-sql-query-order-of-operations.htm – Davos 2014-06-24 04:32:08

4

我會想象因爲在處理完WHERE子句和生成數據之後,別名纔會被分配給結果列。 Oracle與此行爲中的其他DBMS不同?

12

因爲documentation說,它不會:

指定的別名列 表達。 Oracle數據庫將在 的列標題中使用 這個別名的結果集。 AS關鍵字是 可選。該別名實際上爲 重命名查詢的持續時間的選擇列表項。別名 可用於查詢中的order_by_clause而不是 其他子句。

但是,如果您有內部選擇,就像創建列別名生效的內聯視圖一樣,因此您可以在外部級別使用它。

2

總之,這個小寶石解釋說:

10 Easy Steps to a Complete Understanding of SQL

混亂的一個常見原因是簡單事實上SQL語法 元素沒有按照它們執行的方式排序。詞法 排序是:

SELECT [ DISTINCT ] 
FROM 
WHERE 
GROUP BY 
HAVING 
UNION 
ORDER BY 

爲簡單起見,不是所有的SQL子句中列出。該詞彙順序 與邏輯順序基本不同,即從 執行順序:

FROM 
WHERE 
GROUP BY 
HAVING 
SELECT 
DISTINCT 
UNION 
ORDER BY 

因此,任何你標籤中使用「AS」一旦WHEREHAVINGGROUP BY已經完成纔可用。