A todos nos ha pasado alguna vez que cuando creamos una columna calculada en la parte del SELECT y queremos usarla en la cláusula WHERE no funciona, pero sin embargo en el ORDER BY vuelve a funcionar. Algo así como:

SELECT TOP 10 SalesOrderID, SalesOrderDetailID, LineTotal, LineTotal * 0.5 AS discount

FROM AdventureWorks.Sales.SalesOrderDetail

WHERE discount > 100.

Esto nos devuelve el mensaje de que «discount» es columna inválida, es decir, que no existe. Sin embargo, la siguiente instrucción se ejecuta perfectamente

SELECT TOP 10 SalesOrderID, SalesOrderDetailID, LineTotal, LineTotal * 0.5 AS discount

FROM AdventureWorks.Sales.SalesOrderDetail

ORDER BY discount

La solución a este problema es sencilla, por lo que buscar la causa de este comportamiento se ve en muchas ocasiones como una pérdida de tiempo. La siguiente modificación hace que la instrucción se ejecute correctamente (no es la única solución, aunque sí la más común)

SELECT TOP 10 SalesOrderID, SalesOrderDetailID, LineTotal, LineTotal * 0.5 AS discount

FROM AdventureWorks.Sales.SalesOrderDetail

WHERE LineTotal * 0.5 > 100.

¿Y esto por qué?

Pues porque, a diferencia de los lenguajes de programación con los que también solemos trabajar, una instrucción SELECT no se ejecuta en el orden en el que está escrita, sino que existe otro orden preestablecido que no podemos modificar: resumidamente (para no alargar esta entrada), primero se procesa la cláusula FROM, luego el WHERE, luego el SELECT y por último el ORDER BY. Ya explicaremos en otra entrada todo el proceso, incluyendo el resto de las cláusulas.

Es decir, que la cláusula WHERE no sabe que tiene una hermana que se llama SELECT ni lo que ésta hace. Sin embargo ORDER BY, al ser la última de la clase, se puede aprovechar del trabajo realizado anteriormente y sabe que su hermana SELECT ha creado una columna nueva que se llama «discount», así que puede usarla directamente J