¿Por qué Oracle SQL no nos permite usar alias de columna en cláusulas GROUP BY?
group-by (5)
Aunque estoy de acuerdo en que sería útil hacer referencia a las expresiones con alias en la cláusula GROUP BY, supongo que no es posible porque la cláusula GROUP BY se evalúa antes de la cláusula SELECT.
Esto también explicaría por qué puede usar alias de columna en la cláusula ORDER BY (es decir: la cláusula ORDER BY se evalúa al final).
Esta es una situación que generalmente enfrento al escribir consultas SQL. Creo que escribir toda la columna (por ejemplo, expresiones de casos largos, funciones de suma con parámetros largos) en lugar de alias en expresiones GROUP BY hace que la consulta sea más larga y menos legible. ¿Por qué Oracle SQL no nos permite usar los alias de columna en la cláusula GROUP BY? Debe haber una razón importante detrás de esto.
No es solo Oracle SQL, de hecho, creo que se ajusta al estándar ANSI SQL (aunque no tengo una referencia para eso). La razón es que la cláusula SELECT se procesa lógicamente después de la cláusula GROUP BY, por lo que en el momento en que se realiza GROUP BY, los alias aún no existen.
Quizás este ejemplo algo ridículo ayude a aclarar el problema y la ambigüedad que SQL está evitando:
SQL> select job as sal, sum(sal) as job
2 from scott.emp
3 group by job;
SAL JOB
--------- ----------
ANALYST 6000
CLERK 4150
MANAGER 8275
PRESIDENT 5000
SALESMAN 5600
Pero algunos RDBMS sí, esto funciona en PostgreSQL:
select emp.lastname || '' '' || emp.firstname as fullname, count(emp_work.*) as cnt
from emp
left join emp_work using(emp_id)
group by fullname
Eso funcionará, siempre que el alias agrupado no sea el resultado de funciones agregadas, group by cnt
no funcionará
Pero puedo arriesgarme a suponer que group by fullname
se expande a group by emp.lastname || '' '' || emp.firstname as fullname
group by emp.lastname || '' '' || emp.firstname as fullname
group by emp.lastname || '' '' || emp.firstname as fullname
, y la cláusula SELECT solo elige el nombre completo del resultado de esa agrupación; aunque sintácticamente mira hacia el otro lado. GROUP siempre se ejecuta primero, luego las proyecciones son las últimas (es decir, SELECT)
Sé que este es un hilo viejo, pero parece que el problema de los usuarios no fue realmente resuelto; las explicaciones fueron buenas para explicar por qué la cláusula group by no permite el uso de alias, pero no se dio ninguna alternativa.
En función de la información anterior, los alias no se pueden usar en el grupo porque desde el grupo se ejecuta primero, antes de que los alias de la cláusula de selección se almacenen en la memoria. Así que la solución simple que funcionó para mi vista fue agregar una selección externa que simplemente selecciona los alias, y luego se agrupa en ese mismo nivel.
Ejemplo:
SELECT alias1, alias2, alias3, aliasN
FROM
(SELECT field1 as alias1, field2 as alias2, field3 as alias3, fieldN as aliasN
FROM tableName
WHERE '' '' = '' '')
GROUP BY alias1, alias2, alias3, aliasN
Bastante sencillo una vez que veas la solución, pero un PITA si intentas darte cuenta por primera vez.
Esta es la única forma en que he podido "agruparme" para un campo derivado de una declaración de caso, por lo que este es un buen truco para saber.
Si bien parece una respuesta lógica, de hecho es muy poco amigable para el usuario. Antes de procesar la consulta, Oracle la lee y, al leerla, el preprocesador puede reemplazar el alias por la declaración original y aún enviar la consulta correcta a la base de datos. Igual que puede codificar orden por 1,2,3, también debería poder agrupar por 1,2,3 o alias.