我正在使用这个简单的相关子查询来找到最接近某个地方的地方(当然是简化示例):
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个最近的地方。显然,相关的子查询在这种情况下不起作用。
答案 0 :(得分:2)
如果我理解你的要求,我认为你应该可以使用这样的rank()
窗口函数:
SELECT * FROM (
SELECT
FromPlaceId,
FromPlaceName,
ToPlaceId,
ToPlaceName,
Distance,
rank = RANK() OVER (PARTITION BY FromPlaceId ORDER BY Distance)
FROM #temp
) a
WHERE rank <= 2;
这将返回每个FromPlaceId的所有ToPlaceId,其距离最接近前两个,因此如果多个ToPlaceId具有相同的距离,则将返回所有ToPlaceId。
更改当前查询以在相关查询中使用in
和top 2
也应该有效,但我认为窗口功能可能会更好。
FROM #temp AS a WHERE a.Distance IN
(
SELECT TOP 2 b.Distance