Sumário
Não há razão lógica para isso não ser possível, mas o benefício é pequeno e existem algumas armadilhas que podem não ser imediatamente aparentes.
Resultados da pesquisa
Eu fiz algumas pesquisas e encontrei algumas informações boas. A seguir, uma citação direta de uma fonte primária confiável (que deseja permanecer anônima) em 09/08/2012 17:49 GMT:
Quando o SQL foi inventado, ele não tinha alias na cláusula SELECT. Essa foi uma falha grave que foi corrigida quando o idioma foi padronizado pelo ANSI em 1986.
O idioma foi planejado para ser "não processual" - em outras palavras, para descrever os dados que você deseja, sem especificar como encontrá-los. Portanto, até onde eu sei, não há razão para que uma implementação SQL não possa analisar toda a consulta antes de processá-la e permitir que aliases sejam definidos em qualquer lugar e usados em qualquer lugar. Por exemplo, não vejo nenhum motivo para a seguinte consulta não ser válida:
select name, salary + bonus as pay
from employee
where pay > 100000
Embora eu ache que essa é uma consulta razoável, alguns sistemas baseados em SQL podem introduzir restrições ao uso de aliases por algum motivo relacionado à implementação. Não me surpreendo ao saber que o SQL Server faz isso.
Estou interessado em mais pesquisas sobre o padrão SQL-86 e por que os DBMS modernos não suportam a reutilização de alias, mas ainda não tive tempo de ir muito longe com ele. Para começar, não sei onde obter a documentação ou como descobrir quem exatamente compôs o comitê. Alguém pode ajudar? Também gostaria de saber mais sobre o produto original da Sybase de onde o SQL Server veio.
A partir desta pesquisa e de algumas reflexões adicionais, suspeitei que o uso de aliases em outras cláusulas, embora seja possível, simplesmente nunca foi uma prioridade tão alta para os fabricantes de DBMS em comparação com outros recursos de idioma. Como não é um obstáculo muito grande, ser facilmente contornado pelo gravador de consultas, não é ideal esforçar-se por outros avanços. Além disso, seria proprietário, pois obviamente não faz parte do padrão SQL (embora eu esteja esperando para descobrir mais sobre isso com certeza) e, portanto, seria uma pequena melhoria, quebrando a compatibilidade SQL entre DBMSes. Por comparação, CROSS APPLY
(que na verdade nada mais é do que uma tabela derivada que permite referências externas) é uma grande mudança, enquanto o proprietário oferece um poder expressivo incrível, que não é facilmente executado de outras maneiras.
Problemas com o uso de aliases em todos os lugares
Se você permitir que itens SELECT sejam inseridos na cláusula WHERE, poderá não apenas explodir a complexidade da consulta (e, portanto, a complexidade de encontrar um bom plano de execução), como também é possível criar coisas completamente ilógicas. Experimentar:
SELECT X + 5 Y FROM MyTable WHERE Y = X
E se MyTable já tiver uma coluna Y, qual é a cláusula WHERE? A solução é usar uma CTE ou uma tabela derivada, que na maioria dos casos não deve custar mais, mas alcança o mesmo resultado final. CTEs e tabelas derivadas, pelo menos, reforçam a resolução de ambiguidade, permitindo que um alias seja usado apenas uma vez.
Além disso, não usar aliases na cláusula FROM faz sentido eminente. Você não pode fazer isso:
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
Isso é uma referência circular (no sentido em que T2 é secretamente referindo-se a um valor de T3, antes que a tabela foi apresentado na lista JOIN), e danado difícil de ver. Que tal este:
INSERT dbo.FinalTransaction
SELECT
newid() FinalTransactionGUID,
'GUID is: ' + Convert(varchar(50), FinalTransactionGUID) TextGUID,
T.*
FROM
dbo.MyTable T
Quanto você quer apostar que a função newid () será colocada no plano de execução duas vezes, fazendo com que as duas colunas mostrem valores diferentes completamente inesperadamente? E quando a consulta acima é usada N níveis de profundidade em CTEs ou tabelas derivadas. Garanto que o problema é pior do que você pode imaginar. Há já graves problemas de inconsistência sobre quando as coisas são avaliadas somente uma vez ou em que ponto em um plano de consulta e Microsoft disse que não vai resolveralguns deles porque estão expressando álgebra de consulta corretamente - se houver resultados inesperados, divida a consulta em partes. Permitir referências encadeadas, detectar referências circulares através de cadeias potencialmente muito longas - esses são problemas bastante complicados. Introduzir paralelismo e você tem um pesadelo em formação.
Nota: O uso do alias em WHERE ou GROUP BY não fará diferença nos problemas com funções como newid () ou rand ().
Uma maneira do SQL Server de criar expressões reutilizáveis
O CROSS APPLY / OUTTER APPLY é uma maneira no SQL Server de criar expressões que podem ser usadas em qualquer outro lugar da consulta (apenas anteriormente na cláusula 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
Isso faz duas coisas:
- Faz com que todas as expressões no CROSS APPLY obtenham um "namespace" (um alias de tabela, aqui, X) e sejam exclusivas dentro desse namespace.
- Torna óbvio em todos os lugares não apenas que o CalcID é proveniente do X, mas também torna óbvio por que você não pode usar nada do X ao ingressar na tabela T1 e T3, porque o X ainda não foi introduzido.
Na verdade, eu gosto bastante de CROSS APPLY. Tornou-se meu amigo fiel, e eu o uso o tempo todo. Precisa de um UNPIVOT parcial (o que exigiria um PIVOT / UNPIVOT ou UNPIVOT / PIVOT usando sintaxe nativa)? Feito com CROSS APPLY. Precisa de um valor calculado que será reutilizado várias vezes? Feito. Precisa aplicar rigidamente a ordem de execução de chamadas em um servidor vinculado? Concluído - com uma gritante melhoria na velocidade. Precisa de apenas um tipo de linha dividida em 2 linhas ou com condições extras? Feito.
Portanto, no mínimo, no DBMS SQL Server 2005 e versões posteriores, você não tem mais motivo para reclamação: CROSS APPLY é como você SECA da maneira que deseja.
No Entity SQL , você PODE usar aliases de expressões em outros lugares da consulta em algumas situações:
Observe que aqui você DEVE definir a expressão na
GROUP BY
cláusula para usá-la naSELECT
cláusula.Obviamente, é possível permitir parte desse tipo de expressão de alias como reutilizável em consultas SQL.
fonte