0

我有一个包含纬度和经度列(都是浮点数)的表,现在我正在构建一个存储过程,它获取一个点作为参数,并查找哪些行距它最远 500 米。

我在 where 子句中使用了以下语句,但它不起作用:

(geometry::STGeomFromText('POINT(' + CAST(Longitude AS VARCHAR(20)) + ' ' + 
  CAST(Latitude AS VARCHAR(20)) 
  + ')', 4326).STDistance(@currentLocation) / 1000) < @radius

@currentLocationgeometry@radiusfloat

我正在使用 SQL Server 2012。我的 where 子句有什么问题?

4

1 回答 1

1

从样式和性能的角度来看,存在几个问题,但就功能而言,查询不起作用的原因是(我猜)您提供的 @radius 参数为 500,期望它搜索500米范围内的位置?

但是,经度和纬度坐标是角坐标,以度为单位,对吧?所以你实际上在做的是找到那些距离@currentLocation 小于 500/1000 度的点(不知道你为什么要除以 1000?)

我猜你真的想为这个查询使用地理数据类型。您还应该使用 Point() 方法而不是 STGeomFromText() 方法,因为它不涉及所有 CAST,所以它会稍微快一些并且更整洁。

您的 WHERE 子句将如下所示:

geography::Point(Latitude, Longitude, 4326).STDistance(@currentLocation) < @radius

这里仍然存在问题 - 因为您只是为查询中的每一行动态创建 geography Point 实例,您将无法使用任何索引,并且查询可能会很慢。更好的方法是在表中创建一个 PERSISTED 计算列:

ALTER TABLE yourTable
ADD Location AS geography::Point(Latitude, Longitude, 4326) PERSISTED;

然后向该列添加空间索引(您需要在表上使用聚集主键),然后您的查询将变为:

SELECT * FROM yourTable
WHERE Location.STDistance(@currentLocation) < 500;
于 2012-11-21T19:17:24.807 回答