为什么这个SQL不能工作?
以下方面:
6371 * ACos( Cos(RADIANS(Latitude)) * Cos(RADIANS('50.017466977673905')) * Cos(RADIANS('24.69924272460935')
- RADIANS(Longitude)) + Sin(RADIANS(Latitude)) * Sin(RADIANS('50.017466977673905')) )子句只计算来自搜索点的订单。
我把它混在一起(因为它太长了)到距离。
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”替换为冗长的短语,它工作得很好。
我甚至可以按列别名订购,这是可行的!!?
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我做错了什么?
发布于 2015-08-04 12:04:18
发生这种情况是因为自然的查询处理顺序,如下所示:
FROMONOUTERWHEREGROUP BYCUBE x- ROLLUPHAVINGSELECTDISTINCTORDER BYTOP在SELECT语句中指定别名。如您所见,WHERE在SELECT和ORDER BY之后被处理。这就是原因。现在有什么解决办法:
CROSS APPLY。这应该会美化您的代码一点,这是推荐的方法。CROSS APPLY将在WHERE语句之前指定别名,使其在其中可用。
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语句的执行顺序是什么?
发布于 2015-08-04 11:56:14
至于为什么不能在WHERE子句中指定别名,这是由于查询处理的逻辑顺序:(http://tsql.solidq.com/books/insidetsql2008/Logical%20Query%20Processing%20Poster.pdf)。
WHERE子句是在SELECT子句之后处理的,而ORDER BY则是在之后处理的。只有在处理了SELECT子句之后才能引用列别名。
发布于 2015-08-04 11:46:46
我建议您使用这样的内部选择:
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:
;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;https://stackoverflow.com/questions/31808423
复制相似问题