首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能在WHERE子句中使用别名名称,但可以按以下顺序使用

不能在WHERE子句中使用别名名称,但可以按以下顺序使用
EN

Stack Overflow用户
提问于 2015-08-04 11:45:00
回答 7查看 976关注 0票数 1

为什么这个SQL不能工作?

以下方面:

代码语言:javascript
复制
6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935')
- RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) )

子句只计算来自搜索点的订单。

我把它混在一起(因为它太长了)到距离。

代码语言:javascript
复制
SELECT   [Hotel Id],
  latitude,
  longitude,
  establishmentname,
  6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) ) AS Distance  
FROM [dbo].[RPT_hotels] 
  WHERE distance < '30' 
  ORDER BY Distance

在这里,我将“距离< 30”替换为冗长的短语,它工作得很好。

我甚至可以按列别名订购,这是可行的!!?

代码语言:javascript
复制
SELECT   [Hotel Id],
  latitude,
  longitude,
  establishmentname,
  6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) ) AS Distance  
FROM [dbo].[RPT_hotels] 
  WHERE 6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) ) < '30' 
  ORDER BY Distance

我做错了什么?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2015-08-04 12:04:18

发生这种情况是因为自然的查询处理顺序,如下所示:

  1. FROM
  2. ON
  3. OUTER
  4. WHERE
  5. GROUP BY
  6. CUBE x- ROLLUP
  7. HAVING
  8. SELECT
  9. DISTINCT
  10. ORDER BY
  11. TOP

SELECT语句中指定别名。如您所见,WHERESELECTORDER BY之后被处理。这就是原因。现在有什么解决办法:

  • 子查询。但它们可能很难读懂。
  • CROSS APPLY。这应该会美化您的代码一点,这是推荐的方法。

CROSS APPLY将在WHERE语句之前指定别名,使其在其中可用。

代码语言:javascript
复制
SELECT [Hotel Id]
    , latitude
    , longitude
    , establishmentname
    , Distance
FROM [dbo].[RPT_hotels]
CROSS APPLY (
    SELECT 6371 * ACos(Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')))
    ) AS T(Distance)
WHERE distance < 30
ORDER BY Distance;

如果你想知道更多。请阅读以下问题:此SQL语句的执行顺序是什么?

票数 6
EN

Stack Overflow用户

发布于 2015-08-04 11:56:14

至于为什么不能在WHERE子句中指定别名,这是由于查询处理的逻辑顺序:(http://tsql.solidq.com/books/insidetsql2008/Logical%20Query%20Processing%20Poster.pdf)。

WHERE子句是在SELECT子句之后处理的,而ORDER BY则是在之后处理的。只有在处理了SELECT子句之后才能引用列别名。

票数 2
EN

Stack Overflow用户

发布于 2015-08-04 11:46:46

我建议您使用这样的内部选择:

代码语言:javascript
复制
SELECT *
FROM (
    SELECT
        [Hotel Id],latitude,longitude,establishmentname,6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) ) AS Distance 
    FROM 
        [dbo].[RPT_hotels] ) t
WHERE Distance < 30 
ORDER BY Distance;

注意,ORDER BY也可以使用别名和列号。

另一种方法是像这样使用CTE

代码语言:javascript
复制
;WITH t AS (
    SELECT
        [Hotel Id],latitude,longitude,establishmentname,6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935') - RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) ) AS Distance 
    FROM 
        [dbo].[RPT_hotels] )
SELECT *
FROM t
WHERE Distance < 30
ORDER BY Distance;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31808423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档