我有一个带有Latitude和Longitude列的表(两者都是浮点数),现在我正在构建一个存储过程,它将一个点作为参数,并找出距离它最远500米的行。
我在where子句中使用以下语句但它不起作用:
(geometry::STGeomFromText('POINT(' + CAST(Longitude AS VARCHAR(20)) + ' ' +
CAST(Latitude AS VARCHAR(20))
+ ')', 4326).STDistance(@currentLocation) / 1000) < @radius
@currentLocation
为geometry
,@radius
为float
。
我正在使用SQL Server 2012.我的where子句出了什么问题?
答案 0 :(得分:1)
从样式和性能的角度来看存在几个问题,但就功能而言,查询不起作用的原因是因为(我猜测)你提供的@radius参数是500,期待它搜索500米范围内的位置?
但是,经度和纬度坐标是角度坐标,以度为单位,对吗?所以你实际上在做的是找到距离@currentLocation不到500/1000度的那些点(不知道你为什么要除以1000?)
我猜你真的想为这个查询使用geography数据类型。您还应该使用Point()方法而不是STGeomFromText()方法,这种方法会更快更整洁,因为它不涉及所有CASTing。
您的WHERE子句将如下所示:
geography::Point(Latitude, Longitude, 4326).STDistance(@currentLocation) < @radius
这里仍然存在问题 - 因为您只是为查询中的每一行动态创建地理点实例,您将无法使用任何索引,并且查询可能会非常慢。更好的方法是在表中创建一个PERSISTED计算列:
ALTER TABLE yourTable
ADD Location AS geography::Point(Latitude, Longitude, 4326) PERSISTED;
然后向此列添加空间索引(您需要在表上使用群集主键),然后您的查询才会变为:
SELECT * FROM yourTable
WHERE Location.STDistance(@currentLocation) < 500;