Domanda SQL: utilizza l'alias in Raggruppa per


Solo curiosità sulla sintassi SQL. Quindi se ho

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY itemName, FirstLetter

Questo sarebbe errato perché

GROUP BY itemName, FirstLetter 

davvero dovrebbe essere

GROUP BY itemName, substring(itemName, 1,1)

Ma perché non possiamo semplicemente usare il primo per comodità?


101
2017-10-01 16:46


origine


risposte:


SQL è implementato come se una query fosse eseguita nel seguente ordine:

  1. Clausola FROM
  2. Dove la clausola
  3. Clausola GROUP BY
  4. Clausola HAVING
  5. Clausola SELECT
  6. Clausola ORDER BY

Per la maggior parte dei sistemi di database relazionali, questo ordine spiega quali nomi (colonne o alias) sono validi perché devono essere stati introdotti in un passaggio precedente.

Pertanto, in Oracle e SQL Server, non è possibile utilizzare un termine nella clausola GROUP BY definita nella clausola SELECT perché GROUP BY viene eseguito prima della clausola SELECT.

Ci sono tuttavia delle eccezioni: MySQL e Postgres sembrano avere un'ulteriore intelligenza che lo consenta.


186
2017-10-01 17:53



È sempre possibile utilizzare una sottoquery in modo da poter utilizzare l'alias; Certo, controlla le prestazioni (possibile che il server db esegua le stesse cose, ma non guasta mai per verificare):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter

21
2017-10-01 16:55



Almeno in PostgreSQL puoi usare il numero di colonna nel set di risultati nella tua clausola GROUP BY:

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY 1, 2

Naturalmente questo inizia a essere un problema se lo si fa in modo interattivo e si modifica la query per modificare il numero o l'ordine delle colonne nel risultato. Ma ancora.


13
2017-10-01 16:49



SQL Server non consente di fare riferimento all'alias nella clausola GROUP BY a causa dell'ordine logico di elaborazione. La clausola GROUP BY viene elaborata prima della clausola SELECT, quindi l'alias non è noto quando viene valutata la clausola GROUP BY. Questo spiega anche perché è possibile utilizzare l'alias nella clausola ORDER BY.

Ecco una fonte di informazioni sul Fasi di elaborazione logica di SQL Server.


9
2017-10-01 17:10



Si noti che l'utilizzo di alias in Raggruppa per (per i servizi che lo supportano, come postgres) può avere risultati non previsti. Ad esempio, se si crea un alias già esistente nell'istruzione interna, Group By sceglierà il nome del campo interno.

-- Working example in postgres
select col1 as col1_1, avg(col3) as col2_1
from
    (select gender as col1, maritalstatus as col2, 
    yearlyincome as col3 from customer) as layer_1
group by col1_1;

-- Failing example in postgres
select col2 as col1, avg(col3)
from
    (select gender as col1, maritalstatus as col2,
    yearlyincome as col3 from customer) as layer_1
group by col1;

3
2018-04-23 13:13



Alcuni DBMS ti consentono di utilizzare un alias invece di dover ripetere l'intera espressione.
Teradata è uno di questi esempi.

Evito la notazione di posizione ordinale come raccomandato da Bill per ragioni documentate in questa domanda SO.

L'alternativa semplice e robusta consiste nel ripetere sempre l'espressione nella clausola GROUP BY.
DRY NON si applica a SQL.


2
2017-10-01 16:53



Fare attenzione all'utilizzo di alias quando si raggruppano i risultati da una vista in SQLite. Otterrai risultati imprevisti se il nome dell'alias è uguale al nome della colonna di qualsiasi tabella sottostante (alle viste).


1
2018-04-28 15:29



Nel corso della giornata ho scoperto che Rdb, l'ex prodotto DEC ora supportato da Oracle, consentiva l'utilizzo dell'alias della colonna in GROUP BY. Oracle principale attraverso la versione 11 non consente l'utilizzo dell'alias di colonna in GROUP BY. Non sono sicuro di ciò che Postgresql, SQL Server, MySQL, ecc. Permetteranno o non permetteranno. YMMV.


0
2017-10-01 16:56



Non sto rispondendo perché è così, ma volevo solo mostrare un modo per aggirare quella limitazione in SQL Server usando CROSS APPLYper creare l'alias. Lo usi quindi nel GROUP BY clausola, in questo modo:

SELECT 
 itemName as ItemName,
 FirstLetter,
 Count(itemName)
FROM table1
CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
GROUP BY itemName, FirstLetter

0
2017-12-13 18:59