查找前 n 个最近的地方

Find top n closest places

我正在使用这个简单的相关子查询来查找离某个地方最近的地方(当然是简化的示例):

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp
CREATE TABLE #Temp
(
    FromPlaceId INT NOT NULL,
    FromPlaceName [NVARCHAR](255) NOT NULL,
    ToPlaceId INT NOT NULL,
    ToPlaceName [NVARCHAR](255) NOT NULL,
    Distance FLOAT NOT NULL 
)

INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 1, N'Place1' , 2 , N'Place2' , 1.0  )
INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 1, N'Place1' , 3 , N'Place3' , 2.0  )
INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 2, N'Place2' , 1 , N'Place1' , 1.0  )
INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 2, N'Place2' , 3 , N'Place3' , 13.0  )
INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 3, N'Place3' , 1 , N'Place1' , 2.0  )
INSERT INTO #Temp( FromPlaceId, FromPlaceName, ToPlaceId, ToPlaceName, Distance) VALUES ( 3, N'Place3' , 2 , N'Place2' , 13.0  )

SELECT * FROM #Temp

SELECT 
    a.FromPlaceId,
    a.FromPlaceName,
    a.ToPlaceId,
    a.ToPlaceName,
    a.Distance
FROM #temp AS a WHERE a.Distance = 
(
    SELECT TOP 1 b.Distance FROM #Temp AS b WHERE a.FromPlaceId = b.FromPlaceId
    ORDER BY b.Distance ASC
)

我只是想知道如何获得最近的 2 或 3 个地点。显然,关联子查询在这种情况下不起作用。

如果我正确理解您的要求,我认为您应该能够像这样使用 rank() window 函数:

SELECT * FROM (
    SELECT 
       FromPlaceId,
       FromPlaceName,
       ToPlaceId,
       ToPlaceName,
       Distance,
       rank = RANK() OVER (PARTITION BY FromPlaceId ORDER BY Distance)
    FROM #temp  
) a
WHERE rank <= 2;

这将 return 每个 FromPlaceId 的所有 ToPlaceId 的距离在前两个最接近的位置,因此如果多个 ToPlaceId 具有相同的距离,则所有 ToPlaceId 都将被 returned。

将您当前的查询更改为在相关查询中使用 intop 2 也应该有效,尽管我认为 window 函数可能执行得更好。

FROM #temp AS a WHERE a.Distance IN
(
    SELECT TOP 2 b.Distance