Как использовать имя столбца псевдонима в предложении where в SQL Server
Когда я попытался выполнить приведенный ниже код в SQL Server 2005, я получаю сообщение об ошибке
Недопустимое имя столбца DistanceFromAddress
код:
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
Я правильно получаю значения с помощью оператора select, но когда я попытался проверить условие where DistanceFromAddress < 2
, я получаю ошибку.
Как я могу решить эту проблему?
Ответы
Ответ 1
Вы не можете использовать столбцы с псевдонимом в предложении WHERE
. Вы можете попробовать использовать производную таблицу. Возможно, что-то вроде этого (извините, не проверено):
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
Ответ 2
Предложение WHERE
обрабатывается перед предложением SELECT
(*), и поэтому псевдонимы недоступны. Перейдите к использованию подзапроса или CTE - здесь 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
(*) - ну, системы могут свободно переупорядочивать операции по мере их соответствия, пока результат "как будто" оператор SQL обрабатывался в некотором логический порядок. Конечно, когда все это происходит не так с SQL Server, где создает ошибки из-за проблем с конверсией в предложении SELECT
для строк/значений, которые следует исключить из предложения WHERE
.
Ответ 3
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
мог бы работать (хотя я думаю, что нет, без предложения group by).
Проблема заключается в том, что вы можете использовать имена только в области таблиц (ов), которые вы выбираете внутри предложения where
. where
- это предварительный фильтр, который отфильтровывает строки до их выбора, поэтому выражение, подобное этому в определении поля, еще не выполнено, и псевдонимы для него недоступны.
Предложение Having
работает как пост-фильтр после группировки и может использовать псевдонимы из запроса, хотя я боюсь, что вам нужно будет иметь фактическое предложение group by
(не уверен).
Альтернативой является наличие подвыборки (производная таблица или выбор в выборе), где вы сначала выбираете расстояния для каждой строки, а затем выбираете только соответствующие расстояния от этих результатов. Это будет работать:
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
Или вы можете повторить выражение. Это затрудняет выполнение запроса, но в некоторых случаях это может сработать для вас. Например, если вы не хотите возвращать фактическое расстояние, но только, скажем, название точки интереса на этом расстоянии. В этом случае вам нужно иметь выражение только в предложении where
, и в этом случае аргумент поддерживаемости исчезнет, и это решение является идеальной альтернативой.
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
Ответ 4
Я думаю, вы можете использовать AS только для отображения окончательных значений. Чтобы выполнить сравнение, выбор должен быть возвращен из другого оператора select внутри него.
Как
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
Вы можете попробовать это.
Ответ 5
select
t1.*,
t2.brand_name,
t3.category_name,
if(
t3.parent_category_id=0,
t3.cat_key,
(
select
concat(t3b.cat_key,'/',t3.cat_key)
from master_category t3b
where t3b.category_id=t3.parent_category_id
)
) as cat_key,
(
select min(t4.product_MSP)
from trans_products t4
where t1.product_id=t4.product_id
) as product_MSP,
(
select min(t4.product_MRP)
from trans_products t4
where t1.product_id=t4.product_id
) as product_MRP
from master_products t1,
master_brand t2,
master_category t3
where t1.status=1
and t2.status=1
and t2.brand_id=t1.brand_id
and t3.category_id=t1.category_id
and t3.display_status=1
and t1.category_id=6
and product_MSP between '1000' and '500000'