SQL Spatial JOIN By Nearest Neighbor

时间:2011-02-20 00:47:37

标签: sql sql-server tsql sql-server-2008 geospatial

在下面的数据中,我正在寻找一个查询,所以我可以加入最近邻居的2个表的结果。

dbo.Interests表中的一些结果不会出现在dbo.Details表中,

这个问题找到k个最近点的单个点,我需要这个查询来进一步协调2个表之间的数据

How can I extend this SQL query to find the k nearest neighbors?

IF OBJECT_ID('dbo.Interests', 'U') IS NOT NULL DROP TABLE dbo.Interests;
IF OBJECT_ID('dbo.Details', 'U') IS NOT NULL DROP TABLE dbo.Details;

CREATE TABLE [dbo].[Interests](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [NAME] [nvarchar](255) NULL,
    [geo] [geography] NULL,
)

CREATE TABLE [dbo].[Details](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [NAME] [nvarchar](255) NULL,
    [geo] [geography] NULL,
)

/*** Sample Data ***/ 

/* Interests */
INSERT INTO dbo.Interests (Name,geo) VALUES ('Balto the Sled Dog',geography::STGeomFromText('POINT(-73.97101284538104 40.769975451779729)', 4326));
INSERT INTO dbo.Interests (Name,geo) VALUES ('Albert Bertel Thorvaldsen',geography::STGeomFromText('POINT(-73.955996808113582 40.788611756916609)', 4326));
INSERT INTO dbo.Interests (Name,geo) VALUES ('Alice in Wonderland',geography::STGeomFromText('POINT(-73.966714294355356 40.7748020248959)', 4326));
INSERT INTO dbo.Interests (Name,geo) VALUES ('Hans Christian Andersen',geography::STGeomFromText('POINT(-73.96756141015176 40.774416211045626)', 4326));

/* Details */
INSERT INTO dbo.Details(Name,geo) VALUES ('Alexander Hamilton',geography::STGeomFromText('POINT(-73.9645616688172 40.7810234271951)', 4326));
INSERT INTO dbo.Details(Name,geo) VALUES ('Arthur Brisbane',geography::STGeomFromText('POINT(-73.953249720745731 40.791599412827864)', 4326));
INSERT INTO dbo.Details(Name,geo) VALUES ('Hans Christian Andersen',geography::STGeomFromText('POINT(-73.9675614098224  40.7744162102582)', 4326));
INSERT INTO dbo.Details(Name,geo) VALUES ('Balto',geography::STGeomFromText('POINT(-73.9710128455336 40.7699754516397)', 4326));

1 个答案:

答案 0 :(得分:1)

蛮力方法是计算所有细节X兴趣记录之间的距离:

SELECT *
FROM
(
SELECT *, rank=dense_rank() over (partition by IName, IGeo order by dist asc)
FROM
(
     SELECT D.NAME as DName, D.geo as DGeo,
        I.NAME as IName, I.geo as IGeo,
        I.geo.STDistance(D.geo) AS dist
     FROM dbo.Details D CROSS JOIN dbo.Interests I
) X
) Y
WHERE rank <= @k

注意:@k是您之后的目标匹配数