56

当我尝试在 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时出现错误。

我该如何解决这个问题?

4

5 回答 5

56

您不能在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
于 2013-04-23T06:07:56.930 回答
38

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子句消除。

于 2013-04-23T06:07:10.417 回答
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
于 2013-04-23T06:07:37.130 回答
0

我认为您只能使用 AS 来显示最终值。要进行比较,选择应该从其中的另一个选择语句返回。

喜欢:

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

你可以试试这个。

于 2013-04-23T06:15:44.467 回答
-2
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' 
于 2019-06-04T13:46:38.970 回答