Resumen
No hay una razón lógica para que no se pueda hacer, pero el beneficio es pequeño y hay algunas dificultades que pueden no ser evidentes de inmediato.
Resultados de la investigacion
Investigué un poco y encontré buena información. La siguiente es una cita directa de una fuente primaria confiable (que desea permanecer en el anonimato) al 2012-08-09 17:49 GMT:
Cuando se inventó SQL por primera vez, no tenía alias en la cláusula SELECT. Esta fue una deficiencia grave que se corrigió cuando el lenguaje fue estandarizado por ANSI aproximadamente en 1986.
El lenguaje estaba destinado a ser "no procesal", en otras palabras, para describir los datos que desea sin especificar cómo encontrarlos. Entonces, hasta donde sé, no hay ninguna razón por la cual una implementación de SQL no pueda analizar toda la consulta antes de procesarla, y permitir que los alias se definan en cualquier lugar y se usen en todas partes. Por ejemplo, no veo ninguna razón por la cual la siguiente consulta no debería ser válida:
select name, salary + bonus as pay
from employee
where pay > 100000
Aunque creo que esta es una consulta razonable, algunos sistemas basados en SQL pueden introducir restricciones en el uso de alias por alguna razón relacionada con la implementación. No me sorprende escuchar que SQL Server hace esto.
Estoy interesado en más investigación sobre el estándar SQL-86 y por qué los DBMS modernos no admiten la reutilización de alias, pero aún no he tenido tiempo de llegar muy lejos con él. Para empezar, no sé dónde obtener la documentación o cómo averiguar quién formó exactamente el comité. ¿Alguien puede ayudar? También me gustaría saber más sobre el producto Sybase original del que proviene SQL Server.
A partir de esta investigación y algunas reflexiones adicionales, he llegado a sospechar que el uso de alias en otras cláusulas, aunque es bastante posible, nunca ha sido una prioridad tan alta para los fabricantes de DBMS en comparación con otras características del lenguaje. Dado que no es un gran obstáculo, el redactor de consultas puede evitarlo con facilidad, por lo que no es óptimo esforzarse por otros avances. Además, sería propietario, ya que obviamente no forma parte del estándar SQL (aunque estoy esperando saber más sobre eso con seguridad) y, por lo tanto, sería una mejora menor, rompiendo la compatibilidad SQL entre DBMS. En comparación, CROSS APPLY
(que en realidad no es más que una tabla derivada que permite referencias externas) es un gran cambio, que si bien el propietario ofrece un increíble poder expresivo que no se realiza fácilmente de otras maneras.
Problemas con el uso de alias en todas partes
Si permite que los elementos SELECT se coloquen en la cláusula WHERE, no solo puede explotar la complejidad de la consulta (y, por lo tanto, la complejidad de encontrar un buen plan de ejecución), es posible encontrar cosas completamente ilógicas. Tratar:
SELECT X + 5 Y FROM MyTable WHERE Y = X
¿Qué sucede si MyTable ya tiene una columna Y, a cuál se refiere la cláusula WHERE? La solución es usar un CTE o una tabla derivada, que en la mayoría de los casos no debería costar más pero logra el mismo resultado final. Los CTE y las tablas derivadas al menos imponen la resolución de la ambigüedad al permitir que un alias se use solo una vez.
Además, no usar alias en la cláusula FROM tiene mucho sentido. No puedes hacer esto:
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
Eso es una referencia circular (en el sentido de que T2 se refiere en secreto a un valor de T3, antes de que la tabla se ha presentado en la lista JOIN), y rematadamente 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
¿Cuánto desea apostar a que la función newid () se incluirá dos veces en el plan de ejecución, haciendo que las dos columnas muestren valores diferentes de forma inesperada? ¿Qué pasa cuando la consulta anterior se utiliza N niveles profundos en CTE o tablas derivadas? Te garantizo que el problema es peor de lo que puedes imaginar. Ya existen serios problemas de inconsistencia sobre cuándo las cosas se evalúan solo una vez o en qué punto de un plan de consulta, y Microsoft ha dicho que no solucionaráalgunos de ellos porque expresan el álgebra de consultas correctamente; si uno obtiene resultados inesperados, divida la consulta en partes. Permitir referencias encadenadas, detectar referencias circulares a través de cadenas potencialmente muy largas, estos son problemas bastante difíciles. Introduce el paralelismo y tendrás una pesadilla en ciernes.
Nota: Usar el alias en WHERE o GROUP BY no va a hacer una diferencia en los problemas con funciones como newid () o rand ().
Una forma de SQL Server para crear expresiones reutilizables
CROSS APPLY / OUTER APPLY es una forma en SQL Server de crear expresiones que se pueden usar en cualquier otro lugar de la consulta (solo que no antes en la 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
Esto hace dos cosas:
- Hace que todas las expresiones en CROSS APPLY obtengan un "espacio de nombres" (un alias de tabla, aquí, X) y sean únicas dentro de ese espacio de nombres.
- Hace evidente en todas partes, no solo que CalcID proviene de X, sino que también hace evidente por qué no puede usar nada de X cuando se une a la tabla T1 y T3, porque X aún no se ha introducido.
En realidad, soy bastante aficionado a CROSS APPLY. Se ha convertido en mi fiel amigo, y lo uso todo el tiempo. ¿Necesita un UNPIVOT parcial (que requeriría un PIVOT / UNPIVOT o UNPIVOT / PIVOT usando la sintaxis nativa)? Hecho con APLICACIÓN CRUZADA. ¿Necesita un valor calculado que se reutilizará muchas veces? Hecho. ¿Necesita imponer rígidamente la orden de ejecución para las llamadas a través de un servidor vinculado? Hecho, con una mejora en la velocidad de gritos. ¿Necesita solo un tipo de fila dividida en 2 filas o con condiciones adicionales? Hecho.
Por lo menos, en DBMS SQL Server 2005 y versiones posteriores, no tiene más motivos para quejarse: CROSS APPLY es la forma en que SECA de la manera que desea.