如何计算 SQL 服务器中多个源的 "Nearest Neighbour"?
How to calculate the "Nearest Neighbour" for multiple sources in SQL Server?
"Nearest Neighbour" 问题在处理空间数据时很常见。
在他们的文档中甚至有一些 nice, simple documentation 关于如何使用 MS Sql 服务器做到这一点!
我经常看到使用 1x 源 Lat/Long 并且 return 是 'x' 个最近邻 Lat/Long 的例子。很好...
例如
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);
在我的例子中,我有 多个 Lat/Long 个来源...并且对于每个来源,需要 return '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
..
所以对于这个 table 中的每个位置,我需要找到最近的..比如 5 个其他位置。
更新
到目前为止,似乎使用 CURSOR
是唯一的方法..但我愿意接受更多基于 set 的解决方案。
您需要在同一集合中找到最近的邻居吗?
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,其本机计量单位是米)。这可能适合也可能不适合你。如果不是,则省略 where
子句。
我觉得这还是一个游标。不要自欺欺人地认为,仅仅因为没有 declare cursor
语句就可以看出数据库引擎有很多选择,只能遍历 table 并评估 apply
对于每一行。
"Nearest Neighbour" 问题在处理空间数据时很常见。
在他们的文档中甚至有一些 nice, simple documentation 关于如何使用 MS Sql 服务器做到这一点!
我经常看到使用 1x 源 Lat/Long 并且 return 是 'x' 个最近邻 Lat/Long 的例子。很好...
例如
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);
在我的例子中,我有 多个 Lat/Long 个来源...并且对于每个来源,需要 return '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
..
所以对于这个 table 中的每个位置,我需要找到最近的..比如 5 个其他位置。
更新
到目前为止,似乎使用 CURSOR
是唯一的方法..但我愿意接受更多基于 set 的解决方案。
您需要在同一集合中找到最近的邻居吗?
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,其本机计量单位是米)。这可能适合也可能不适合你。如果不是,则省略where
子句。我觉得这还是一个游标。不要自欺欺人地认为,仅仅因为没有
declare cursor
语句就可以看出数据库引擎有很多选择,只能遍历 table 并评估apply
对于每一行。