Подтвердить что ты не робот

Как использовать имя столбца псевдонима в предложении 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, я получаю ошибку.

Как я могу решить эту проблему?

4b9b3361

Ответ 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'