SQL Server 2008:空间查询 - 返回最近的5个站点

时间:2014-12-31 11:47:06

标签: sql-server-2008 loops spatial-query

我尝试使用SQL Server 2008创建原始/目标矩阵选择。我想找到距离任何给定站点最近的5个站点。

矩阵应包括原点ID,目的地ID和两者之间的距离。到目前为止,我已经设法为一个站点工作,但我想循环遍历表中的每一行。在找出如何做到这一点时,我已经碰壁了,有人可以帮忙吗?如果它们距离原址2.5公里,我只想返回一个目的地。

我的一个原始网站的工作代码如下(我想要相同的输出,但包括所有行作为原点):

SP_Geometry是我的地理列(使用EasyLoader时,MapInfo默认为此列命名)

DECLARE @Point1 AS Geography
DECLARE @Point1ID AS Nvarchar (255)
SELECT @Point1=SP_Geometry FROM SitesTable WHERE Label = 'ID1'
SELECT @Point1ID = Label FROM SitesTable WHERE Label = 'ID1'

SELECT TOP 5
@Point1ID AS Origin
,@Point1 AS Origin_SP_Geometry
,@Point1.STDistance(SP_Geometry) AS Distance
,@Label AS Destination
,SP_Geometry AS Destination_SP_Geometry

FROM SiteTable
WHERE @Point1.STDistance(SP_Geometry) <2500
ORDER BY @Point1.STDistance(SP_Geometry)

在以下选择中运行以上结果:

+--------+---------------------+-------------+-------------+----------------------------+
| Origin | Origin_SP_GEOMETRY  |  Distance   | Destination |  Destination_SP_GEOMETRY   |
+--------+---------------------+-------------+-------------+----------------------------+
| ID1    | 0xE6100000010CDD(…) | 0           | ID1         | 0xE6100000010CDD772D9D(…)  |
| ID1    | 0xE6100000010CDD(…) | 395.7739586 | ID867       | 0xE6100000010C2466CDFA5(…) |
| ID1    | 0xE6100000010CDD(…) | 407.6394398 | ID2500      | 0xE6100000010C6FBC54(…)    |
| ID1    | 0xE6100000010CDD(…) | 1033.827269 | ID91        | 0xE6100000010C3981C0353(…) |
| ID1    | 0xE6100000010CDD(…) | 1082.667065 | ID1540      | 0xE6100000010CD03BFCD2(…)  |
+--------+---------------------+-------------+-------------+----------------------------+

理想情况下,这正是我想要的,但是在建立任何类型的循环(联合起源ID2,ID3等)时遇到了麻烦。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

尝试使用RANK功能。我无法测试,因为我没有样本数据所以这可能需要调整,但应该关闭......

;WITH cteDistances AS (
    SELECT 
         origin.Label AS OriginId
        ,dest.Label AS DestinationId
        ,origin.SP_Geometry.STDistance(dest.SP_Geometry) AS Distance
        ,RANK() OVER (PARTITION BY origin.Label ORDER BY origin.SP_Geometry.STDistance(dest.SP_Geometry)) AS DistanceRank
    FROM 
        SiteTable origin
        INNER JOIN SiteTable dest ON (dest.Label <> origin.Label)
    WHERE 
        origin.SP_Geometry.STDistance(dest.SP_Geometry) < 2500
)       

SELECT 
    OriginId, DestinationId, Distance
FROM 
    cteDistances 
WHERE 
    DistanceRank <= 5