postgres表中的最近点
nearest point in postgres tables
当且仅当最近的条目在 10 英里以内时,我需要一些帮助来找到特定 table 的每个条目到另一个条目的最近点。
2 table 在这里:
Table A
lon | lat | block_id
和
table B
city | latitude | longitude | block_id
-------------------+----------+-----------+----------
现在,我必须将 table A 的 blockid 更新为距离该条目最近且在 10 英里以内的 Table B 之一。如果找不到匹配项,可能会更新它 "NA"。 Table A 包含一百万个条目,table B 10 个条目。
我正在使用 postgres 9.4。我是 postgres 的新手,因此在里面不是很舒服 table 虽然相当舒服 table 和 sql.
如有错误请多多包涵。非常感谢您的帮助,我被困住了。
非常感谢,
你能创建一个几何类型的字段列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
非常感谢 Juan 的帮助,这是我执行的步骤列表:
添加列
ALTER TABLE tableA
ADD COLUMN geom
geometry(Geometry,4326);
ALTER TABLE tableB
ADD COLUMN geom
geometry(Geometry,4326);
然后编辑表A中的geom列,对表B也是如此:
update tableA set geom=ST_SetSRID(ST_Point(lon, lat),4326)::geometry;
然后得到对应的block_id
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 block_id 匹配,我想 select 最近的 block_id。
再次感谢,
苏迪普
在 'location' 字段上创建索引,并且位置字段具有点数据类型。
CREATE INDEX ON table_name USING GIST(location);
GiST 索引能够优化“nearest-neighbor”搜索:
SELECT * FROM table_name ORDER BY location <-> point '(-74.013, 40.711)' LIMIT 10;
注:该点第一个元素为经度,第二个元素为纬度。
当且仅当最近的条目在 10 英里以内时,我需要一些帮助来找到特定 table 的每个条目到另一个条目的最近点。
2 table 在这里:
Table A
lon | lat | block_id
和
table B
city | latitude | longitude | block_id
-------------------+----------+-----------+----------
现在,我必须将 table A 的 blockid 更新为距离该条目最近且在 10 英里以内的 Table B 之一。如果找不到匹配项,可能会更新它 "NA"。 Table A 包含一百万个条目,table B 10 个条目。
我正在使用 postgres 9.4。我是 postgres 的新手,因此在里面不是很舒服 table 虽然相当舒服 table 和 sql.
如有错误请多多包涵。非常感谢您的帮助,我被困住了。
非常感谢,
你能创建一个几何类型的字段列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
非常感谢 Juan 的帮助,这是我执行的步骤列表:
添加列
ALTER TABLE tableA
ADD COLUMN geom
geometry(Geometry,4326);
ALTER TABLE tableB
ADD COLUMN geom
geometry(Geometry,4326);
然后编辑表A中的geom列,对表B也是如此:
update tableA set geom=ST_SetSRID(ST_Point(lon, lat),4326)::geometry;
然后得到对应的block_id
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 block_id 匹配,我想 select 最近的 block_id。
再次感谢, 苏迪普
在 'location' 字段上创建索引,并且位置字段具有点数据类型。
CREATE INDEX ON table_name USING GIST(location);
GiST 索引能够优化“nearest-neighbor”搜索:
SELECT * FROM table_name ORDER BY location <-> point '(-74.013, 40.711)' LIMIT 10;
注:该点第一个元素为经度,第二个元素为纬度。