Я начал играть со SpatiaLite сегодня и уже наткнулся на проблему.
Для каждой точки, сохраненной в tableOne, я бы хотел выбрать одну, ближайшую (линейное расстояние) точку из tableTwo.
До сих пор я придумал неуклюжее решение, которое использует VIEW:
CREATE VIEW testview AS
SELECT
A.id ,
B.myValue,
Distance(A.Geometry, B.Geometry) AS distance
FROM tableOne AS A, tableTwo AS B
WHERE distance < 10000
ORDER BY A.Id, distance;
А потом:
SELECT * FROM testview
WHERE distance = (SELECT MIN(distance) FROM testview AS t WHERE t.id = testview.id)
кажется, делает работу.
Два вопроса:
Есть ли способ выполнить такой запрос без создания VIEW?
Есть ли другой способ оптимизировать этот запрос для повышения производительности? В реальном сценарии tableOne будет иметь сотни-пару тысяч записей, а tableTwo - 1,3 миллиона.
Ответы:
Я только что проверил этот SQL, и он работает:
Как вы можете прочитать здесь: «Наивный способ выполнить запрос ближайшего соседа - упорядочить таблицу кандидатов по расстоянию от геометрии запроса, а затем взять запись с наименьшим расстоянием».
С наилучшими пожеланиями,
Andrea
источник
Если вы не хотите вычислять расстояния между всеми комбинациями точек, вы можете использовать пространственный индекс для одной из таблиц:
источник
f_table_name = 'A'
, мне нужно заменить 'A' на фактическое имя таблицы (таблица одна)? Я пытался в любом случае, и он до сих пор ничего не возвращает, почему это может бытьf_table_name = 'A'
должны бытьf_table_name = 'tableOne'
. Обратите внимание, что этот запрос предполагает пространственный размер> 4.x (используетсяSpatialIndex
виртуальная таблица). Вы пытались настроитьsearch_frame
для вашего случая использования? В приведенном выше примере предполагается, что точки находятся на максимальном расстоянии 10000 метров.Начиная с версии 4.4.0 SpatiaLite поддерживает индекс виртуальной таблицы KNN для проблем ближайшего соседа. Вот запрос, который находит ближайшую строку в таблице линейных линий для каждой точки в таблице точек.
источник
Вы можете упростить ваш запрос следующим образом.
Для более общего решения, возможно, стоит попытаться преобразовать эту функцию ближайшего соседа PostGIS: http://blog.mackerron.com/2011/03/postgis-nearest-neighbour/
источник
SQL error: "misuse of aggregate: MIN()"