Perché Oracle SQL non ci consente di utilizzare alias di colonne nelle clausole GROUP BY?

Questa è una situazione che generalmente sto affrontando mentre scrivo query SQL. Penso che scrivere l’intera colonna (es. Espressioni a lungo termine, funzioni di sum con parametri lunghi) invece di alias nelle espressioni GROUP BY rende la query più lunga e meno leggibile. Perché Oracle SQL non ci consente di utilizzare gli alias di colonna nella clausola GROUP BY? Ci deve essere una ragione importante dietro di esso.

Non è solo Oracle SQL, infatti credo che sia conforms allo standard ANSI SQL (anche se non ho un riferimento per questo). Il motivo è che la clausola SELECT viene elaborata logicamente dopo la clausola GROUP BY, quindi al momento in cui viene eseguito GROUP BY gli alias non esistono ancora.

Forse questo esempio un po ‘ridicolo aiuta a chiarire il problema e l’ambiguità che SQL sta 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 

So che questo è un thread vecchio, ma sembra che il problema degli utenti non sia stato davvero risolto; le spiegazioni sono state utili per spiegare perché la clausola group by non consente di utilizzare alias, ma non è stata fornita alcuna alternativa.

In base alle informazioni di cui sopra, gli alias non possono essere utilizzati nel gruppo in quanto gruppo per prime, prima che gli alias dalla clausola select vengano archiviati in memoria. Quindi la soluzione semplice che ha funzionato per il mio punto di vista era aggiungere una selezione esterna che selezionasse semplicemente gli alias e quindi gruppi allo stesso livello.

Esempio:

 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 

Piuttosto semplice, una volta che vedi la soluzione, ma una PITA se cerchi di capire da solo per la prima volta.

Questo è l’unico modo in cui sono stato in grado di “raggruppare” per un campo derivato da una dichiarazione del caso, quindi questo è un buon trucco da sapere.

Mentre sono d’accordo sarebbe utile fare riferimento alle espressioni con alias nella clausola GROUP BY, suppongo che non sia ansible perché la clausola GROUP BY viene valutata prima della clausola SELECT.

Ciò spiegherebbe anche perché è ansible utilizzare gli alias di colonna nella clausola ORDER BY (cioè: la clausola ORDER BY viene valutata per ultima).

Anche se sembra una risposta logica, in effetti è molto poco amichevole. Prima di elaborare la query, Oracle lo legge e, leggendolo, il preprocessore può sostituire l’alias con l’istruzione originale e inviare comunque la query corretta al database. allo stesso modo in cui puoi codificare l’ordine di 1,2,3, dovresti anche essere in grado di raggruppare per 1,2,3 o alias.

Ma alcuni RDBMS lo fanno, questo funziona su 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 

Ciò funzionerà, a patto che l’alias raggruppato non sia il risultato di funzioni aggregate, group by cnt non funzionerà

Ma posso azzardare un’ipotesi che il group by fullname venga espanso per group by emp.lastname || ' ' || emp.firstname as fullname group by emp.lastname || ' ' || emp.firstname as fullname group by emp.lastname || ' ' || emp.firstname as fullname e la clausola SELECT seleziona il risultato del nome completo da quel raggruppamento; sebbene sintatticamente sembra il contrario. GROUP esegue sempre prima, quindi le proiezioni durano (cioè SELECT)