处理空间数据时,“最近邻”问题非常常见。
甚至还有一些nice, simple documentation关于如何使用 MS Sql Server 在他们的文档中做到这一点!
我通常会看到使用 1x 源纬度/经度并返回最近邻纬度/经度的“x”号的示例。很好...
例如
USE AdventureWorks2012
GO
DECLARE @g geography = 'POINT(-121.626 47.8315)';
SELECT TOP(7) SpatialLocation.ToString(), City FROM Person.Address
WHERE SpatialLocation.STDistance(@g) IS NOT NULL
ORDER BY SpatialLocation.STDistance(@g);
就我而言,我有多个纬度/经度源...并且对于每个源,需要返回最近邻居的“x”个数。
这是我的架构
Table: SomeGeogBoundaries
LocationId INTEGER PRIMARY KEY (it's not an identity, but a PK & FK)
CentrePoint GEOGRAPHY
Index:
Spatial Index on CentrePoint column. [Geography || MEDIUM, MEDIUM, HIGH, HIGH]
示例数据:
LocationId | CP Lat/Long
1 | 10,10
2 | 11,11
3 | 20,20
..
因此,对于此表中的每个位置,我需要找到最接近的......比如说 5 个其他位置。
更新
到目前为止,看起来使用 CURSOR
是唯一的方法..但我愿意接受更多基于集合的解决方案。
最佳答案
您需要找到同一集合中最近的邻居吗?
SELECT *
FROM SomeGeogBoundaries as b
OUTER APPLY (
SELECT TOP(5) CentrePoint
FROM SomeGeogBoundaries as t
WHERE t.CentrePoint.STInsersects(b.CentrePoint.STBuffer(100))
ORDER by b.CentrePoint.STDistance(t.CentrePoint)
) AS nn
两个注释。
outer apply
中的where
子句将搜索限制为(在本例中)彼此相距 100 米以内的点(假设您使用的 SRID 的 native 测量单位是米)。这可能适合也可能不适合您。如果没有,只需省略where
子句即可。我认为这仍然是一个光标。不要欺骗自己,仅仅因为没有任何
declarecursor
语句可见,数据库引擎就有很多选择,只能迭代您的表并评估apply
每行。
关于sql-server - 如何计算SQL Server中多个源的 "Nearest Neighbour"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43222318/