You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostGIS SQL查询示例:筛选A表中位于B表半径范围内的行

PostGIS 查询示例:筛选表A中位于表B半径范围内的行

基础查询语句

假设表A、B的经纬度采用WGS84坐标系(EPSG:4326,绝大多数GPS/地图数据的标准),且表B的radius单位为米,可以用以下查询:

SELECT DISTINCT a.*
FROM 表A a
JOIN 表B b 
  ON ST_DWithin(
      -- 将表A的经纬度转为地理类型(用于球面距离计算)
      ST_SetSRID(ST_MakePoint(a.longitude, a.latitude), 4326)::geography,
      -- 将表B的经纬度转为地理类型
      ST_SetSRID(ST_MakePoint(b.longitude, b.latitude), 4326)::geography,
      -- 表B的半径(单位:米)
      b.radius
  );

关键说明

  • ST_MakePoint(longitude, latitude):PostGIS中点的坐标顺序是经度在前,纬度在后,不要搞反
  • ::geography:转换为地理类型后,ST_DWithin会基于球面计算真实地表距离,比平面几何计算更符合实际场景
  • DISTINCT:避免表A的同一行被表B中多个符合条件的条目重复返回

优化与简化

  1. 空间索引(大数据量必加)
    如果表A或B的数据量较大,创建空间索引能大幅提升查询速度:
-- 给表A创建空间索引
CREATE INDEX idx_a_geography ON 表A USING GIST (ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::geography);

-- 给表B创建空间索引
CREATE INDEX idx_b_geography ON 表B USING GIST (ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::geography);
  1. 利用表B已有的point字段
    如果表B的point字段已经是PostGIS空间类型(geometry或geography),可以直接替换构造点的语句,简化查询:
SELECT DISTINCT a.*
FROM 表A a
JOIN 表B b 
  ON ST_DWithin(
      ST_SetSRID(ST_MakePoint(a.longitude, a.latitude), 4326)::geography,
      b.point::geography,
      b.radius
  );

注意事项

  • 如果表B的radius单位是千米,记得乘以1000转换成米
  • 如果必须使用平面几何计算(比如特定投影坐标系),去掉::geography转换,确保ST_SetSRID指定对应的平面坐标系EPSG代码

内容的提问来源于stack exchange,提问作者Čamo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:12:20