SQL - максимальное расстояние между рядами точек - PullRequest
0 голосов
/ 18 января 2019

Извините, если я пропустил его в другом месте, есть ли способ найти наибольшее расстояние между списком точек (x, y)?

Пример данных

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Ответ от 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;
0 голосов
/ 18 января 2019

Вы можете перекрестное соединение, чтобы получить все комбинации точек, а затем использовать теорему Пифагора, чтобы найти расстояния. Это, вероятно, неэффективно для большого набора данных, хотя.

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

(Обратите внимание, что вам может понадобиться что-то более сложное, если вы хотите увидеть все наборы точек в случае наличия связей).

...