SQL-系列点之间的最大距离

时间:2019-01-18 00:14:31

标签: sql max distance

对不起,如果我在其他地方错过了它,是否可以找到点列表(x,y)之间的最大距离?

Sample data

2 个答案:

答案 0 :(得分:1)

您可以交叉合并以获取所有点的组合,然后使用勾股定理找到距离。但是,这对于大型数据集而言可能效率不高。

Select *, sqrt(power(a.x-b.x, 2) + power(a.y-b.y, 2)) as Distance
from MyData a
Join MyData b
on a.locationcode > b.locationcode --so you don't get all combination of points a,b and b,a returned

您也可以将其写为MyData a cross join MyData b,然后过滤掉连接在一起的行(或忽略它们,因为在这种情况下,距离将为0)。

要得到最大的东西,就像这样:

Select top 1 *, sqrt(power(a.x-b.x, 2) + power(a.y-b.y, 2)) as Distance
from MyData a
Join MyData b
on a.locationcode > b.locationcode
order by Distance desc

(注意,如果要在有联系的情况下查看所有点集,则可能需要更复杂的东西)。

答案 1 :(得分:1)

APH的答案是完全正确的,但如上所述,可能会遇到大型数据集的问题。为了将来的读者受益,我将发布对大型数据集应该有效的替代方案:

  1. 找到点集的质心
  2. 找到质心最远的顶点
  3. 找到最远顶点与任何其他顶点之间的最长边

这是SQL Server的解决方案:

-- Find the centroid of the set of points
DECLARE @centroid_x DECIMAL(18,6);
DECLARE @centroid_y DECIMAL(18,6);
SET @centroid_x = (SELECT AVG(x) FROM points);
SET @centroid_y = (SELECT AVG(y) FROM points);

-- Find the furthest vertex from the centroid
DROP TABLE IF EXISTS #furthest_point;
SELECT
    x, y
INTO #furthest_point
FROM (
    SELECT
        points.x,
        points.y,
        ROW_NUMBER() OVER (ORDER BY SQRT((points.x - @centroid_x)^2 + (points.y - @centroid_y)^2) DESC) AS rn
    FROM points
) fp
WHERE fp.rn = 1;

-- Find the longest edge between the furthest vertex and any other vertex
SELECT
    MAX(
        SQRT(
            POWER(fp.x - p.x, 2) + POWER(fp.y - p.y, 2)
        )
    ) AS maximum_distance
FROM points p
CROSS JOIN furthest_point fp;