streszczenie
Nie ma logicznego powodu, dla którego nie można tego zrobić, ale korzyść jest niewielka i istnieją pewne pułapki, które mogą nie być natychmiast widoczne.
Winiki wyszukiwania
Przeprowadziłem badania i znalazłem dobre informacje. Poniżej znajduje się bezpośredni cytat z wiarygodnego źródła pierwotnego (które chce pozostać anonimowy) o 08.08.2012 17:49 GMT:
Kiedy SQL został wymyślony po raz pierwszy, nie zawierał aliasów w klauzuli SELECT. Było to poważne niedociągnięcie, które zostało naprawione, gdy język został znormalizowany przez ANSI w około 1986 roku.
Język miał być „nieprocesowy” - innymi słowy, aby opisywać potrzebne dane bez określania, jak je znaleźć. O ile wiem, nie ma powodu, dla którego implementacja SQL nie mogła przeanalizować całego zapytania przed przetworzeniem go i pozwolić, aby aliasy były definiowane w dowolnym miejscu i używane wszędzie. Na przykład nie widzę żadnego powodu, dla którego poniższe zapytanie powinno być nieprawidłowe:
select name, salary + bonus as pay
from employee
where pay > 100000
Chociaż myślę, że jest to rozsądne zapytanie, niektóre systemy oparte na SQL mogą wprowadzać ograniczenia dotyczące używania aliasów z pewnych powodów związanych z implementacją. Nie jestem zaskoczony, że SQL Server to robi.
Interesują mnie dalsze badania nad standardem SQL-86 i dlaczego współczesne DBMS nie obsługują ponownego użycia aliasu, ale nie miałem jeszcze czasu, aby się z tym za daleko posunąć. Na początek nie wiem, skąd wziąć dokumentację ani jak dowiedzieć się, kto dokładnie utworzył komitet. Czy ktoś może pomóc? Chciałbym również dowiedzieć się więcej o oryginalnym produkcie Sybase, z którego pochodzi SQL Server.
Na podstawie tych badań i dalszych przemyśleń zacząłem podejrzewać, że stosowanie aliasów w innych klauzulach, choć całkiem możliwe, po prostu nigdy nie było tak wysokim priorytetem dla producentów DBMS w porównaniu z innymi funkcjami językowymi. Ponieważ nie jest to zbyt duża przeszkoda, ponieważ autor łatwego do obejścia problemu łatwo go obejść, włożenie w to wysiłku nad innymi osiągnięciami nie jest optymalne. Dodatkowo byłby zastrzeżony, ponieważ oczywiście nie jest częścią standardu SQL (choć na pewno czekam, aby dowiedzieć się więcej na ten temat), a zatem byłby drobnym ulepszeniem, łamiącym zgodność SQL między DBMS. W stosunku,CROSS APPLY
(która tak naprawdę nie jest niczym więcej niż tabelą pochodną, która pozwala na zewnętrzne odniesienia), jest ogromną zmianą, która, choć własna, oferuje niesamowitą moc ekspresji, której nie można łatwo wykonać w inny sposób.
Problemy z używaniem aliasów w dowolnym miejscu
Jeśli zezwolisz na umieszczanie elementów SELECT w klauzuli WHERE, możesz nie tylko rozwikłać złożoność zapytania (a tym samym złożoność znalezienia dobrego planu wykonania), ale możesz wymyślić zupełnie nielogiczne rzeczy. Próbować:
SELECT X + 5 Y FROM MyTable WHERE Y = X
Co jeśli MyTable ma już kolumnę Y, do której odnosi się klauzula WHERE? Rozwiązaniem jest użycie CTE lub tabeli pochodnej, która w większości przypadków nie powinna kosztować więcej, ale osiąga ten sam końcowy wynik. CTE i tabele pochodne przynajmniej wymuszają rozwiązanie niejednoznaczności, umożliwiając użycie aliasu tylko raz.
Również nieużywanie aliasów w klauzuli FROM ma sens. Nie możesz tego zrobić:
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
Jest to cykliczne odniesienie (w tym sensie, że T2 potajemnie odnosi się do wartości z T3, zanim ta tabela została przedstawiona na liście JOIN) i jest cholernie trudne do zobaczenia. Co powiesz na ten:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
Ile chcesz się założyć, że funkcja newid () zostanie dwukrotnie umieszczona w planie wykonania, zupełnie nieoczekiwanie powodując, że dwie kolumny będą miały różne wartości? Co powiesz na to, kiedy powyższe zapytanie zostanie użyte N poziomy głęboko w CTE lub tabelach pochodnych. Gwarantuję, że problem jest gorszy, niż możesz sobie wyobrazić. Istnieją już poważne problemy z niespójnością dotyczące tego, kiedy rzeczy są oceniane tylko raz lub w jakim momencie w planie zapytań, a Microsoft powiedział, że nie naprawiniektóre z nich, ponieważ poprawnie wyrażają algebrę zapytań - jeśli otrzymamy nieoczekiwane wyniki, podziel zapytanie na części. Zezwolenie na łańcuchowe odniesienia, wykrywanie cyklicznych odniesień poprzez potencjalnie bardzo długie takie łańcuchy - to dość skomplikowane problemy. Po wprowadzeniu paralelizmu powstaje koszmar.
Uwaga: użycie aliasu w GDZIE lub GROUP BY nie zmieni problemów z funkcjami takimi jak newid () lub rand ().
Sposób SQL Server do tworzenia wyrażeń wielokrotnego użytku
ZASTOSOWANIE KRZYŻOWE / ZASTOSOWANIE ZEWNĘTRZNE jest jednym ze sposobów SQL Server do tworzenia wyrażeń, których można użyć w dowolnym miejscu zapytania (tylko nie wcześniej w klauzuli 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
To robi dwie rzeczy:
- Sprawia, że wszystkie wyrażenia w aplikacji CROSS APPLY uzyskują „przestrzeń nazw” (alias tabeli, tutaj, X) i są unikalne w obrębie tej przestrzeni nazw.
- Sprawia, że wszędzie widać nie tylko, że CalcID pochodzi z X, ale także wyjaśnia, dlaczego nie można używać niczego z X podczas dołączania do tabel T1 i T3, ponieważ X nie został jeszcze wprowadzony.
Właściwie bardzo lubię CROSS APPLY. Stał się moim wiernym przyjacielem i używam go cały czas. Potrzebujesz częściowego UNPIVOT (który wymagałby PIVOT / UNPIVOT lub UNPIVOT / PIVOT przy użyciu natywnej składni)? Zrobione z APLIKACJĄ KRZYŻOWĄ. Potrzebujesz obliczonej wartości, która będzie wielokrotnie używana? Gotowy. Potrzebujesz sztywno egzekwować polecenie wykonania dla połączeń przez połączony serwer? Zrobione z krzyczącą poprawą prędkości. Potrzebujesz tylko jednego rodzaju podziału wiersza na 2 wiersze lub z dodatkowymi warunkami? Gotowy.
Przynajmniej w DBMS SQL Server 2005 i nowszych nie masz już żadnych powodów do narzekań: CROSS APPLY to sposób SUSZENIA w sposób, w jaki chcesz.
W Entity SQL możesz MOŻE używać aliasów z wyrażeń w innych miejscach zapytania w niektórych sytuacjach:
Zauważ, że tutaj MUSISZ zdefiniować wyrażenie w
GROUP BY
klauzuli, aby użyć go wSELECT
klauzuli.Oczywiście możliwe jest zezwolenie na tego rodzaju wyrażenia alias-as-wielokrotnego użytku w zapytaniach SQL.
źródło