sql - 如何扩展此SQL查询以找到k个最近的邻居?

标签 sql sql-server-2008 geospatial nearest-neighbor

我有一个充满二维数据的数据库- map 上的点。每个记录都有一个几何类型的字段。我需要做的就是将一个点传递给存储过程,该存储过程返回k个最近的点(k也将传递给sproc,但这很容易)。我在http://blogs.msdn.com/isaac/archive/2008/10/23/nearest-neighbors.aspx处找到了一个查询,该查询获取了最近的单个邻居,但是我不知道如何扩展它以找到k个最近的邻居。

这是当前查询-T是表,g是geometry字段,@x是要搜索的点,Numbers是具有1到n的整数的表:

DECLARE @start FLOAT = 1000; 
WITH NearestPoints AS
(
     SELECT TOP(1) WITH TIES *,  T.g.STDistance(@x) AS dist
     FROM Numbers JOIN T WITH(INDEX(spatial_index)) 
     ON T.g.STDistance(@x) < @start*POWER(2,Numbers.n)
     ORDER BY n
)
SELECT TOP(1) * FROM NearestPoints
ORDER BY n, dist

内部查询选择最近的非空区域,然后外部查询从该区域中选择最靠前的结果。外部查询可以轻松更改为(例如)SELECT TOP(20),但是如果最近的区域仅包含一个结果,则您将无法执行该操作。

我认为我可能需要递归搜索包含k条记录的第一个区域,但不使用表变量(这将导致维护问题,因为您必须创建表结构并且易于更改-字段很多),我看不出来

最佳答案

如果从内部查询中删除TOP (1) WITH TIES并将外部查询设置为返回前k行,会发生什么情况?

我也想知道这项修正案是否有帮助。它应该比使用TOP更有效:

DECLARE @start FLOAT = 1000
        ,@k INT = 20
        ,@p FLOAT = 2;

WITH NearestPoints AS
(
     SELECT *
            ,T.g.STDistance(@x) AS dist
            ,ROW_NUMBER() OVER (ORDER BY T.g.STDistance(@x)) AS rn
     FROM Numbers 
     JOIN T WITH(INDEX(spatial_index)) 
     ON   T.g.STDistance(@x) <  @start*POWER(@p,Numbers.n)
     AND (Numbers.n - 1 = 0 
          OR T.g.STDistance(@x) >= @start*POWER(@p,Numbers.n - 1)
         )
)
SELECT * 
FROM NearestPoints
WHERE rn <= @k;

注意:未经测试-我无法在此处访问SQL 2008。

关于sql - 如何扩展此SQL查询以找到k个最近的邻居?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2522948/

相关文章:

mysql - MySQL 的 Haversine 公式的逆向?

r - 绘制 R 地区粮农组织捕鱼区 map

c# - DataSet 中 DataRelation 的用途是什么?

mysql - 如何在给定附加 ID 的情况下按最近日期排序

sql - 根据另一列中的特定字符在计算 SQL 列中构建字符串

SQL服务器: Get total days between two dates

database - 查找存储过程的参数名称

sql-server - 我如何在 Sql 2008 中执行此空间查询?

MySQL地理空间查询

java - Hibernate 检查注解