SQL Spatial JOIN Nearest Neighbor

In the data below, I am looking for a query so that I can join the results of two tables as a nearest neighbor.

Some results in the dbo.Interests table will not appear in the dbo.Details table,

This question finds k closest poins for one point, I need this query to further reconcile data between two tables

How can I expand this SQL query to find 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));
+3
source share
1 answer

The brute-force approach will be to calculate the distance between all data of X interests:

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

NotE: @k - target number of matches after

+1
source

Source: https://habr.com/ru/post/1793319/


All Articles