
窗口函数、聚合函数实际是PostgreSQL中的概念,如果之前使用过应该不会陌生,PostGIS作为空间数据扩展,提供了针对空间数据的窗口函数和聚合函数,在实际空间数据处理分析应用中也有着广泛使用,很有必要单独用一章节对两个概念以及应用进行讲解。
一、核心概念与区别
1. 聚合函数
聚合函数用于将多行数据合并为一个结果,例如计算总和、平均值或合并几何对象。PostGIS 扩展了标准 SQL 聚合函数,增加了空间数据处理能力,例如:
- ST_Union:合并多个几何对象为一个无重叠的几何体。
- ST_Collect:将几何对象聚合为集合(如 GeometryCollection),不改变原始数据。
- ST_SummaryStatsAgg:计算栅格数据集的统计信息(如均值、总和)。
2. 窗口函数
窗口函数在不减少行数的情况下,对数据进行分组计算,常用于分析数据的分布或趋势。PostGIS 的窗口函数支持空间聚类和动态统计,例如:
- ST_ClusterDBSCAN:基于密度的空间聚类,返回每个几何对象所属的簇 ID。
- ST_ClusterKMeans:基于 K-means 算法的空间聚类。
- ST_Lead/ST_Lag:访问当前行前后的行数据(标准 SQL 窗口函数)。
3. 核心区别
窗口函数可以在查询结果的每一行上计算值,而聚合函数则对一组行进行计算。它们可以结合使用,例如在一个窗口函数中使用聚合函数,或者在聚合函数中使用窗口函数
| 特性 | 聚合函数 | 窗口函数 |
|---|---|---|
| 结果行数 | 减少(每组一行) | 保持不变(每行新增列) |
| 典型用途 | 数据合并、统计汇总 | 空间聚类、滑动窗口分析、排名 |
| 空间处理能力 | 强(合并几何、栅格统计) | 中(空间聚类) |
| 常用函数示例 | ST_Union, ST_Collect, ST_SummaryStatsAgg | ST_ClusterDBSCAN, ST_ClusterKMeans, ROW_NUMBER |
二、典型应用案例
案例 1:空间聚类分析(窗口函数)
使用ST_ClusterDBSCAN对城市建筑进行密度聚类,识别密集区域:
sql
-- 找出距离小于20米且至少包含2个建筑的簇
SELECT
gid,
name,
ST_ClusterDBSCAN(geom, eps := 0.0002, minpoints := 2) OVER () AS cluster_id
FROM buildings;
输出结果中,每个建筑被分配到一个簇 ID,便于后续分析密集区域的分布。
案例 2:栅格数据统计(聚合函数)
使用ST_SummaryStatsAgg计算多个栅格瓦片的统计信息:
sql
-- 统计栅格波段1的平均值、总和和标准差
SELECT
ST_SummaryStatsAgg(rast, 1) AS stats
FROM satellite_images;
结果返回包含统计信息的结构体,如平均值(mean)、总和(sum)等。
案例 3:几何数据融合(聚合函数)
使用ST_Union合并多个城市的行政边界:
sql
-- 合并武汉都市圈核心区"武鄂黄黄"
SELECT
ST_AsGeoJSON(ST_Union(geom)) AS merged_geom
FROM biz_city
WHERE city_name IN ('武汉市', '鄂州市', '黄冈市','黄石市');
结果生成一个无重叠的合并几何对象,用于区域分析。
三、核心函数列表
1. 常用聚合函数
| 函数 | 功能 |
|---|---|
| ST_Union | 合并几何对象,消除重叠部分 |
| ST_Collect | 聚合几何对象为集合(如 GeometryCollection),不改变原始数据 |
| ST_SummaryStatsAgg | 计算栅格数据集的统计信息(均值、总和、标准差等) |
| ST_Extent | 返回几何对象的最小外包矩形(Bounding Box) |
| ST_3DExtent | 返回 3D 几何对象的最小外包长方体 |
| ST_Accum | 聚合几何对象为数组,支持 3D 数据 |
2. 常用窗口函数
| 函数 | 功能 |
|---|---|
| ST_ClusterDBSCAN | 基于密度的空间聚类,返回簇 ID |
| ST_ClusterKMeans | 基于 K-means 算法的空间聚类,需指定簇数 K |
| ROW_NUMBER() | 为每个分区内的行分配唯一序号(标准 SQL 窗口函数) |
| ST_Lead/ST_Lag | 访问当前行前后的行数据(标准 SQL 窗口函数) |
| ST_ClusterWithin | 按距离阈值聚类,返回簇 ID(聚合函数也可作为窗口函数使用) |
四、最佳实践与性能优化
1. 空间索引加速
对几何列创建 GIST 索引,加速空间查询和聚类:
sql
CREATE INDEX idx_buildings_geom ON buildings USING GIST (geom);
栅格列建议使用ST_Cluster或ST_Intersects进行空间过滤,减少计算量。
2. 窗口函数参数优化
- ST_ClusterDBSCAN:合理设置eps(距离阈值)和minpoints(最小点数),避免过拟合或欠拟合。
- ST_ClusterKMeans:通过交叉验证选择最佳簇数 K,避免主观设定导致偏差。
3. 聚合函数的选择策略
- ST_Union vs ST_Collect :
- 若需合并几何对象并消除重叠,使用ST_Union。
- 若需保留原始几何结构,使用ST_Collect。
- ST_SummaryStatsAgg:结合sample_percent参数(0-1)对大型栅格数据进行采样统计,提升效率。
4. 栅格数据处理技巧
- 滑动窗口分析:使用标准窗口函数(如ROWS BETWEEN)结合栅格函数(如ST_ValueCount)实现邻域统计:
sql
-- 计算每个像素周围3x3邻域的像素值分布
SELECT
rid,
ST_ValueCount(rast, 1) OVER (ORDER BY rid ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS neighbor_counts
FROM raster_table;
分块处理:对超大型栅格数据按瓦片分区,并行处理后再合并结果。
5. 3D 数据处理
使用ST_3DExtent和ST_Accum处理 3D 几何数据,例如分析建筑物的高度分布:
sql
-- 计算3D建筑模型的最小外包长方体
SELECT
ST_3DExtent(geom) AS bbox_3d
FROM building_models;
五、总结与对比
| 场景 | 推荐函数 | 优势 |
|---|---|---|
| 几何数据合并 | ST_Union, ST_Collect | 高效处理空间重叠,保留原始结构 |
| 空间聚类分析 | ST_ClusterDBSCAN, ST_ClusterKMeans | 基于密度或 K-means 算法,适合点、线、面数据 |
| 栅格统计分析 | ST_SummaryStatsAgg, ST_Histogram | 支持采样和全量统计,返回详细统计信息 |
| 动态排名与趋势分析 | ROW_NUMBER(), ST_Lead/ST_Lag | 标准 SQL 语法,易于实现时间序列或空间序列分析 |
| 3D 数据处理 | ST_3DExtent, ST_Accum | 专门处理 3D 几何对象,支持复杂空间分析 |
PostGIS的窗口函数和聚合函数为空间数据处理提供了灵活且高效的工具。在实际应用中,需根据数据类型、分析目标和性能要求选择合适的函数,并结合索引优化和分块处理提升效率。