sql-server-2005 - operador - select sql ejemplos
Cómo usar el nombre de columna de alias en cláusula where en SQL Server (4)
Cuando traté de realizar el siguiente código en SQL Server 2005 recibo el error
Nombre de columna inválido DistanceFromAddress
Código:
select
SQRT(POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)) * 62.1371192 AS DistanceFromAddress
from
tblProgram
where
DistanceFromAddress < 2
Estoy obteniendo los valores correctamente usando la instrucción select, pero cuando intenté verificar la condición where DistanceFromAddress < 2
recibo el error.
¿Cómo puedo resolver este problema?
Creo que solo puedes usar AS para mostrar los valores finales. Para hacer una comparación, la selección debe ser devuelta desde otra instrucción de selección dentro de ella.
Me gusta:
SELECT a.disfromaddr FROM
( SELECT SQRT(POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)) * 62.1371192
AS DistanceFromAddress FROM tblProgram)
a WHERE a.disfromaddr < 2
Puedes probar esto.
La cláusula WHERE
se procesa antes de la cláusula SELECT
(*), por lo que los alias no están disponibles. Pase a usar una subconsulta o CTE : aquí hay un CTE:
; with Distances as (
select SQRT(POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)) * 62.1371192
AS DistanceFromAddress
from tblProgram
)
select * from Distances where DistanceFromAddress < 2
(*) - bueno, los sistemas pueden reordenar las operaciones como mejor les parezca, siempre que el resultado sea "como si" la sentencia SQL se procesara en un orden lógico determinado. Por supuesto, donde todo esto sale mal con SQL Server es donde produce errores debido a problemas de conversión en la cláusula SELECT
para filas / valores que deberían ser eliminados por la cláusula WHERE
.
No puede usar columnas con alias en una cláusula WHERE
. Puedes intentar usar una tabla derivada. Tal vez algo como esto (lo siento, no probado):
SELECT * FROM
(SELECT SQRT(POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)) * 62.1371192
AS DistanceFromAddress from tblProgram) mytable
WHERE DistanceFromAddress < 2
select
SQRT(
POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)
) * 62.1371192 AS DistanceFromAddress
from tblProgram
having DistanceFromAddress < 2
podría funcionar (aunque creo que no, sin tener una cláusula group by también).
El problema es que solo puede usar nombres en el alcance de la (s) tabla (s) que seleccione dentro de la cláusula where
. Where
hay un filtro previo que filtra las filas antes de que se seleccionen, por lo que expresiones como esta en la definición de campo no se ejecutan aún y los alias no están disponibles por lo tanto?
La cláusula Having
funciona como un filtro de publicación después de la agrupación y puede usar alias de la consulta, aunque me temo que tendrá que tener una cláusula group by
(no estoy seguro).
La alternativa es tener una sub selección (tabla derivada o seleccionar en seleccionar), donde primero selecciona las distancias para cada fila, y luego selecciona solo las distancias relevantes de esos resultados. Esto funcionará:
select d.DistanceFromAddress
from
(select
SQRT(
POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)
) * 62.1371192 AS DistanceFromAddress
from tblProgram) d
where d.DistanceFromAddress < 2
O puedes repetir la expresión. Esto hace que su consulta sea más difícil de mantener, pero en algunos casos esto podría funcionar para usted. Por ejemplo, si no desea devolver la distancia real, pero solo, por ejemplo, el nombre del punto de interés a esa distancia. En ese caso, debe tener la expresión solo en la cláusula where
, en cuyo caso el argumento de mantenibilidad ha desaparecido, y esta solución es una alternativa perfecta.
select
tblProgram.POIname
/* Only if you need to return the actual value
, SQRT(
POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)
) * 62.1371192 AS DistanceFromAddress */
from tblProgram
where
-- Use this if you only want to filter by the value.
SQRT(
POWER(cast(Program_Latitude as float) - cast(''41.5126237'' as float), 2) +
POWER(cast(Program_Longitude as float) - cast(''-81.6516411'' as float), 2)
) * 62.1371192 < 2