导读:本期聚焦于小伙伴创作的《如何在SQL中对地理位置坐标进行网格分组统计?利用经纬度换算函数实现》,敬请观看详情。把分散的经纬度点按固定大小网格聚合,是热力图和业务围栏统计的常见需求。直接对浮点经纬度做GROUP BY会产生海量细碎分组,失去统计意义。借助geohash或自写换算函数,将连续坐标映射为整数网格编号,再用该编号分组,既能控制粒度又可利用数据库索引。本文以MySQL和PostgreSQL为例,说明如何通过经纬度换算函数把坐标转为网格ID,并编写分组统计查询,同时比较精度与性能差异,帮助你在位置分析中快速落地网格聚合。

在地理位置数据分析中,我们常常需要将散落的经纬度坐标按照一定空间粒度进行聚合统计,例如统计每个一平方公里网格内的订单量或用户数。如果直接对经纬度字段做分组,由于浮点数精度问题会产生极多无意义的分组。通过经纬度换算函数将坐标映射到网格编号,再基于编号分组,是一种简单高效的方案。

如何在SQL中对地理位置坐标进行网格分组统计?利用经纬度换算函数实现

为什么需要网格分组统计

原始经纬度是连续型数值,两条记录哪怕只相差零点零零零一度,也会被数据库视为不同值。当数据量达到几十万行时,直接按经纬度字段GROUP BY几乎等同于逐行输出,既慢又无业务价值。业务方通常关心的是某个区域整体的密度,而不是某一个精确点。

网格分组的核心思想是:把地球表面切分成大小相近的方块,每个方块赋予一个唯一编号。同一方块内的所有坐标都归到同一个编号下,统计时只需对编号计数即可。这种方式既能压缩分组数量,又能保留空间分布特征,非常适合热力图、基站负荷、配送区划等场景。

利用自定义换算函数生成网格ID

如果不想引入扩展模块,可以用简单的数学换算把经纬度转成网格行列号。以每格零点零一度为例,将经度加一百八十、纬度加九十后除以粒度并取整,即可得到全局统一的网格坐标。

-- MySQL 自定义函数:将经纬度转换为网格ID(粒度由参数控制)
DELIMITER $$
CREATE FUNCTION lat_lng_to_grid(
  p_lng DOUBLE,
  p_lat DOUBLE,
  p_step DOUBLE
) RETURNS BIGINT
BEGIN
  DECLARE grid_x BIGINT;
  DECLARE grid_y BIGINT;
  -- 经度范围约 -180~180,纬度范围约 -90~90
  SET grid_x = FLOOR((p_lng + 180.0) / p_step);
  SET grid_y = FLOOR((p_lat + 90.0) / p_step);
  -- 组合为唯一ID,防止不同行列冲突
  RETURN grid_x * 100000 + grid_y;
END$$
DELIMITER ;

上述函数把二维坐标压缩成一维整数,查询时直接调用即可。例如统计每个网格的打车订单数:

SELECT
  lat_lng_to_grid(lng, lat, 0.1) AS grid_id,
  COUNT(*) AS order_cnt
FROM taxi_orders
WHERE create_time >= '2023-01-01'
GROUP BY grid_id
ORDER BY order_cnt DESC
LIMIT 20;

这种写法的优点是纯SQL原生、不依赖插件,任何支持自定义函数的数据库都能用。缺点是需要自己把控粒度与编号溢出问题,当步长过小时grid_x乘以倍数可能超出BIGINT范围,此时可改为拼接字符串或使用两个字段分别存行列。

使用GeoHash函数简化实现

PostgreSQL配合PostGIS扩展提供了现成的ST_GeoHash函数,可以把几何点转成字符串哈希,前缀相同的点即位于相近区域。取哈希前若干位即为网格层级。

-- PostgreSQL + PostGIS 按geohash前6位分组
SELECT
  SUBSTRING(ST_GeoHash(ST_MakePoint(lng, lat), 6) FROM 1 FOR 6) AS geo_grid,
  COUNT(*) AS user_cnt
FROM app_users
GROUP BY geo_grid
HAVING COUNT(*) > 50;

GeoHash的层级与精度对应关系明确:第6级约对应一点二公里见方,第7级约零点三公里。相比自定义函数,它考虑了地球曲率且社区通用,便于和前端可视化库打通。但要注意,GeoHash存在跨经线或跨赤道时相邻格子编码突变的问题,严格邻接分析时需配合邻居函数补充。

性能与索引建议

无论使用哪种换算方式,都建议在表中冗余一个网格ID字段,并在该字段上建普通B树索引,而不是每次查询都实时计算函数。可通过触发器或写入时计算来维护。

方案精度控制跨库兼容适用场景
自定义换算函数灵活,步长自定高,纯SQL轻量统计、无扩展环境
GeoHash固定层级需PostGIS等空间邻近、可视化对接

对于超大规模数据,还可将网格ID作为分区键做范围分区,使统计查询只扫描相关分区。如果业务只需近似结果,采样或预聚合表也能进一步降低响应时间。

小结

通过经纬度换算函数把坐标转成网格编号,是SQL中实现位置聚合统计的实用路径。自定义函数适合简单可控的场晧,GeoHash则在与空间生态集成时更省心。核心原则是把连续空间离散化,再用常规分组手段产出可解读的区域指标。

SQLgeohash经纬度网格修改时间:2026-08-05 22:42:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。