Выберите ближайшую точку для каждой строки в таблице - PullRequest
0 голосов
/ 06 мая 2018

Я использую это, чтобы найти ближайшую точку

SELECT 
  id, 
  ST_Distance(
   POINT(52.760667210533,-7.22646337599035),
   geo_point
  ) as distance 
from Points 
order by distance limit 1

У меня есть временная таблица TempPoints со всеми точками-кандидатами, и я хочу нормализовать их на узлах OSM, но их много, поэтому мне нужен один запрос, чтобы разрешить их все за один вызов. UNION не позволяет мне использовать order by, а мой интерфейс необработанных запросов к БД не позволяет мне просто запускать серию запросов, разделенных символом ';'. Временная таблица имеет значения lat и lon, но может также иметь ТОЧКУ. Как я могу пойти

select id,NearestTo(TempPoint.geo_point,Points) from TempPoints;

РЕДАКТИРОВАТЬ: я могу заключить в скобки каждый выбор в моем большом запросе объединения, который решает мою проблему.

Я бы хотел присоединиться к ближайшему ряду.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Мое решение состоит в том, чтобы выдать серию запросов, по одному для каждой строки, и связать их вместе с UNION. Стек mysql взорвется в конце концов, поэтому вам нужно делать их в блоках, но при нормальной установке 1000 в порядке. Вы должны заключить в скобки запросы, так как они включают порядок. Некоторые точки могут потерпеть неудачу, поэтому я помечаю их все буквальной последовательностью line_no, чтобы вы могли редактировать и фильтровать оригиналы. Вам также нужно ограничить запрос с помощью

WHERE Contains(<polygon>,point) 

, иначе он попытается отсортировать всю таблицу, где многоугольник - это ограничивающий прямоугольник, который вы должны создать с помощью GEOMFROMTEXT () и POLYGON (). И, конечно, вам нужен специальный пространственный индекс для столбца! Вот код

            var SMALL=0.001

            var=query=points
                .map(function(point){
                    var bottom=point.lat+SMALL
                    var top=point.lat-SMALL
                    var left=point.lon-SMALL
                    var right=point.lon+SMALL
                    var polygon=[
                        [bottom,left],
                        [top,left],
                        [top,right],
                        [bottom,right],
                        [bottom,left]
                    ]
                    polygon="POLYGON(("+polygon.map(function(point){
                        return point.join(' ')
                    })
                    .join(",")+"))"

                    point.line_no=line_no++
                    return "(SELECT "+point.line_no+" as line_no,id, ST_Distance(POINT("+
                                point.lat+","+point.lon+
                                "),geo_point) as distance"+
                                " from Points "+
                                " WHERE Contains(GeomFromText('"+polygon+"'),geo_point) "+
                                " order by distance limit 1) "
                })
                .join(" UNION ")+" order by line_no"
            return sequelize.query(query)
0 голосов
/ 06 мая 2018

Это может работать для вас:

SELECT t.id as tid, p.id as pid, p.geo_point
FROM TempPoint t
JOIN Points p ON p.id = (
    SELECT p1.id
    FROM Points p1
    ORDER BY ST_Distance(p1.geo_point, t.geo_point)
    LIMIT 1
)
...