Sommario
Non c'è alcun motivo logico per cui non si possa fare, ma il vantaggio è piccolo e ci sono alcune insidie che potrebbero non essere immediatamente evidenti.
Risultati della ricerca
Ho fatto delle ricerche e ho trovato delle buone informazioni. Quanto segue è una citazione diretta da una fonte primaria affidabile (che desidera rimanere anonima) alle 09-08-2012 17:49 GMT:
Quando SQL è stato inventato per la prima volta, non aveva alias nella clausola SELECT. Questo fu un grave difetto che fu corretto quando la lingua fu standardizzata dall'ANSI verso il 1986.
La lingua doveva essere "non procedurale", in altre parole, per descrivere i dati desiderati senza specificare come trovarli. Quindi, per quanto ne so, non c'è motivo per cui un'implementazione SQL non possa analizzare l'intera query prima di elaborarla e consentire agli alias di essere definiti ovunque e utilizzati ovunque. Ad esempio, non vedo alcun motivo per cui la seguente query non dovrebbe essere valida:
select name, salary + bonus as pay
from employee
where pay > 100000
Sebbene ritenga che questa sia una domanda ragionevole, alcuni sistemi basati su SQL possono introdurre restrizioni sull'uso degli alias per qualche motivo relativo all'implementazione. Non sono sorpreso di sapere che SQL Server fa questo.
Sono interessato a ulteriori ricerche sullo standard SQL-86 e sul perché i moderni DBMS non supportano il riutilizzo dell'alias, ma non ho ancora avuto il tempo di andare molto lontano. Per i principianti, non so dove ottenere la documentazione o come scoprire chi ha creato esattamente il comitato. Qualcuno può dare una mano? Vorrei anche sapere di più sul prodotto Sybase originale da cui proveniva SQL Server.
Da questa ricerca e da qualche altro pensiero, sono arrivato a sospettare che l'uso di alias in altre clausole, sebbene del tutto possibile, semplicemente non sia mai stata una priorità così alta per i produttori di DBMS rispetto ad altre funzionalità linguistiche. Dal momento che non è un grosso ostacolo, essendo facilmente aggirabile dallo scrittore di query, lo sforzo su altri progressi non è ottimale. Inoltre, sarebbe proprietario in quanto ovviamente non fa parte dello standard SQL (anche se sto aspettando di saperne di più su questo di sicuro) e quindi sarebbe un piccolo miglioramento, rompendo la compatibilità SQL tra DBMS. In confronto, CROSS APPLY
(che in realtà non è altro che una tabella derivata che consente riferimenti esterni) è un enorme cambiamento, che mentre il proprietario offre un'incredibile potenza espressiva non facilmente eseguibile in altri modi.
Problemi con l'utilizzo degli alias ovunque
Se permetti che gli elementi SELECT vengano inseriti nella clausola WHERE, non solo puoi esplodere la complessità della query (e quindi la complessità di trovare un buon piano di esecuzione), ma è possibile inventare cose completamente illogiche. Provare:
SELECT X + 5 Y FROM MyTable WHERE Y = X
Cosa succede se MyTable ha già una colonna Y, a quale si riferisce la clausola WHERE? La soluzione consiste nell'utilizzare un CTE o una tabella derivata, che nella maggior parte dei casi non dovrebbe costare alcun extra ma raggiunge lo stesso risultato finale finale. I CTE e le tabelle derivate applicano almeno la risoluzione dell'ambiguità consentendo di utilizzare un alias una sola volta.
Inoltre, non usare alias nella clausola FROM ha un senso eminente. Non puoi farlo:
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
FROM
Table1 T
INNER JOIN Table2 T2
ON T2.ID = CalcID
INNER JOIN Table3 T3
ON T2.ID = T3.ID
È un riferimento circolare (nel senso che T2 fa segretamente riferimento a un valore di T3, prima che quella tabella sia stata presentata nell'elenco JOIN), e dannatamente difficile da vedere. Che ne dici di questo:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
Quanto vuoi scommettere che la funzione newid () verrà inserita nel piano di esecuzione due volte, rendendo inaspettatamente completamente le due colonne che mostrano valori diversi? Che dire di quando viene utilizzata la query sopra N livelli profondi in CTE o tabelle derivate. Garantisco che il problema è peggiore di quanto tu possa immaginare. Esistono già seri problemi di incoerenza su quando le cose vengono valutate una sola volta o in quale punto del piano di query e Microsoft ha affermato che non risolveràalcuni perché esprimono correttamente l'algebra delle query - se si ottengono risultati imprevisti, suddividere la query in parti. Consentire riferimenti concatenati, rilevare riferimenti circolari attraverso catene potenzialmente molto lunghe, sono problemi piuttosto delicati. Introduci il parallelismo e hai un incubo in preparazione.
Nota: l'uso dell'alias in WHERE o GROUP BY non farà la differenza per i problemi con funzioni come newid () o rand ().
Un modo di SQL Server per creare espressioni riutilizzabili
CROSS APPLY / OUTER APPLY è un modo in SQL Server per creare espressioni che possono essere utilizzate in qualsiasi altro punto della query (appena non prima nella clausola FROM):
SELECT
X.CalcID
FROM
Table1 T
INNER JOIN Table3 T3
ON T.ID = T3.ID
CROSS APPLY (
SELECT
T3.ID + (SELECT Min(Interval) FROM Intervals WHERE IntName = 'T') CalcID
) X
INNER JOIN Table2 T2
ON T2.ID = X.CalcID
Questo fa due cose:
- Rende tutte le espressioni in CROSS APPLY uno "spazio dei nomi" (un alias di tabella, qui, X) e diventa unica all'interno di quello spazio dei nomi.
- Rende evidente dappertutto non solo che CalcID proviene da X, ma rende anche ovvio il motivo per cui non è possibile utilizzare nulla da X quando si uniscono le tabelle T1 e T3, poiché X non è stato ancora introdotto.
In realtà sono abbastanza affezionato a CROSS APPLY. È diventato il mio fedele amico, e lo uso sempre. Hai bisogno di un UNPIVOT parziale (che richiederebbe un PIVOT / UNPIVOT o UNPIVOT / PIVOT usando la sintassi nativa)? Fatto con CROSS APPLY. Hai bisogno di un valore calcolato che verrà riutilizzato più volte? Fatto. È necessario applicare rigidamente l'ordine di esecuzione per le chiamate su un server collegato? Fatto-con un urlante miglioramento della velocità. Hai bisogno di un solo tipo di riga divisa in 2 righe o con condizioni extra? Fatto.
Quindi, almeno, in DBMS SQL Server 2005 e versioni successive, non hai ulteriori motivi di reclamo: CROSS APPLY è il modo in cui ASCIUGA nel modo che desideri.