2011-05-27 13 views
6

Tengo una consultaDescripción del alias de Oracle: ¿por qué no se reconoce un alias en una consulta a menos que esté envuelto en una segunda consulta?


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

que ejecuta muy bien. Quiero restringir aún más la consulta con una instrucción WHERE. El siguiente paso (humanamente) lógico es modificar la consulta followingly:


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

Sin embargo, esto resulta en un mensaje de error ORA-00904: "CNT": identificador inválido. Por alguna razón, envolviendo la consulta en otra consulta produce el resultado deseado:


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

¿Por qué Oracle no reconoce el alias de "CNT" en la segunda consulta?

+1

Como nota al margen: esta consulta (con agregados) se escribe mejor con la cláusula HAVING: "select count (\ *) cnt, imei from device group by imei having count (\ *)> 1" –

Respuesta

8

La respuesta simple es que la cláusula AS define cómo se llamará a la columna en el resultado, que es un ámbito diferente de la consulta en sí.

En su ejemplo, mediante la cláusula HAVING funcionaría mejor:

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

En la pregunta del OP , no es solo que HAVING funcione mejor, sino que HAVING es la respuesta. No se puede aplicar una cláusula where a un agregado como count (*), que es la razón por la cual existe la cláusula HAVING. Además, según el orden de procesamiento SQL estándar, WHERE sucede antes de SELECT, por lo que el alias CNT ni siquiera existe en el momento en que se aplica la cláusula WHERE. De, Dónde, Agrupar por, Tener, Seleccionar el pedido Por http://www.bennadel.com/blog/70-sql-query-order-of-operations.htm – Davos

4

Me imagino porque el alias no está asignado a la columna de resultados hasta después de que se haya procesado la cláusula WHERE y se hayan generado los datos. ¿Oracle es diferente de otros DBMS en este comportamiento?

12

Debido a que el documentation dice que no:

especificar un alias para la columna expresión. Oracle Database usará este alias en el encabezado de columna el conjunto de resultados. La palabra clave AS es opcional. El alias efectivamente cambia el nombre del elemento de la lista de selección para la duración de la consulta . El alias puede ser utilizado en la orden_por_claús pero no otras cláusulas en la consulta.

Sin embargo, cuando tiene una selección interna, es como crear una vista en línea donde los alias de las columnas entran en vigencia, por lo que puede usar eso en el nivel externo.

2

En resumen, esta pequeña joya explica:

10 Easy Steps to a Complete Understanding of SQL

Una fuente común de confusión es el simple hecho de que los elementos de la sintaxis SQL no están ordenados en la forma en que se ejecutan. El léxico orden es:

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

Por simplicidad, no se muestran todas las cláusulas SQL. Este orden léxico difiere fundamentalmente del orden lógico, es decirDel orden de ejecución :

FROM 
WHERE 
GROUP BY 
HAVING 
SELECT 
DISTINCT 
UNION 
ORDER BY 

Como consecuencia, cualquier cosa que usted etiqueta utilizando "AS" sólo estará disponible una vez que el WHERE, HAVING y GROUP BY ya se han realizado.

Cuestiones relacionadas