ближайшая точка в таблицах postgres - PullRequest
0 голосов
/ 12 февраля 2019

Мне нужна помощь в поиске ближайших точек каждой записи определенной таблицы к другой, если и только если ближайшая запись находится в пределах 10 миль.

2 таблицы находятся здесь:

Table A
lon | lat | block_id 

и

table B
 city        | latitude | longitude | block_id
-------------------+----------+-----------+----------

Теперь мне нужно обновить blockid таблицы A на тот, который находится ближе всего к таблице Bэта запись и если в пределах 10 миль.Если совпадение не найдено, возможно, обновите его «NA».Таблица A состоит из миллиона записей, таблица B - 10 записей.

Я работаю с postgres 9.4.Я довольно новичок в postgres, следовательно, не очень удобно в нем, хотя довольно удобно с sql.

Пожалуйста, потерпите меня, если есть какие-либо ошибки.Большое спасибо за вашу помощь, я застрял плохо.

Большое спасибо,

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Большое спасибо Хуану за помощь, вот список шагов, которые я сделал для реализации:

, чтобы добавить столбцы

ALTER TABLE tableA
  ADD COLUMN geom
    geometry(Geometry,4326);

ALTER TABLE tableB
  ADD COLUMN geom
    geometry(Geometry,4326);

Затем отредактировать столбец geom в таблице A, то же самоедля таблицы B:

update tableA set geom=ST_SetSRID(ST_Point(lon, lat),4326)::geometry;

Затем, чтобы получить соответствующий идентификатор_блока

with cte as (
      SELECT A.id, A.lat, A.lon, B.latitude, B.longitude, B.city, A.geom, B.geom, B.block_id,
             ST_Distance(A.geom::geography, B.geom::geography) as dist
      FROM tableA as A
      CROSS JOIN tableB as B
      WHERE ST_Distance(A.geom::geography, B.geom::geography) < 50000 -- for 50kms
) update tableA set block_id=cte.block_id from cte as cte where tableA.id=cte.id;

Но я не могу добавить дополнительную логику в приведенном выше запросе: если совпадают 2 идентификатора_блока, я хочувыберите ближайший к блоку идентификатор.

Еще раз спасибо, Судип

0 голосов
/ 13 февраля 2019

Вы можете создать столбец поля geom с типом геометрии?обновить с помощью ST_point.

Затем вы делаете

with cte as (
      SELECT A.geom, B.geom, B.block_id,
             ST_Distance(A.geom, B.geom) as dist -- check this value first
      FROM TableA as A
      CROSS JOIN TableB as B
      WHERE ST_Distance(A.geom, B.geom) < 16000 -- 10 miles
)
SELECT *
FROM  cte

РЕДАКТИРОВАТЬ:

Предположим, что ваш CTE работает, тогда вы можете найти ближайшую точку, как это

with cte as (
  ....
), sort as (
   SELECT *, row_number() over (partition by A.id order by dist) as  rn
   FROM cte
)
SELECT *
FROM sort 
WHERE rn = 1
...