如何在PostgreSQL中按15天间隔分组统计日期字段结果
PostgreSQL按15天间隔统计月度数据解决方案
要实现按月拆分1-15日、16日至月末两个区间统计(包含无数据的区间),你需要先构造固定的时间段维度表,再关联业务数据统计,避免直接GROUP BY业务数据导致的重复或遗漏问题。
完整SQL示例
WITH date_ranges AS ( -- 生成目标统计周期内每个月的第一天,自行调整起止日期 SELECT generate_series('2023-02-01'::date, '2023-03-01'::date, '1 month'::interval) AS month_start ), split_ranges AS ( -- 生成当月1-15日的区间 SELECT month_start AS range_start, (month_start + interval '14 days')::date AS range_end, TO_CHAR(month_start, 'YYYY-MM-DD') || ' to ' || TO_CHAR(month_start + interval '14 days', 'YYYY-MM-DD') AS display_date FROM date_ranges UNION ALL -- 生成当月16日至月末的区间 SELECT (month_start + interval '15 days')::date AS range_start, (month_start + interval '1 month - 1 day')::date AS range_end, TO_CHAR(month_start + interval '15 days', 'YYYY-MM-DD') || ' to ' || TO_CHAR((month_start + interval '1 month - 1 day'), 'YYYY-MM-DD') AS display_date FROM date_ranges ) -- 关联业务表统计每个区间的数据量 SELECT sr.display_date AS "Date", COUNT(t.your_date_column) AS "Count" FROM split_ranges sr LEFT JOIN your_table t ON t.your_date_column BETWEEN sr.range_start AND sr.range_end GROUP BY sr.display_date, sr.range_start ORDER BY sr.range_start;
关键说明
- 构造固定时间段维度:用
generate_series生成每个月的起始日期,再通过UNION ALL拆分出每个月的两个固定区间,确保所有需要统计的时间段都被覆盖,包括无数据的区间。 - 左连接统计:通过
LEFT JOIN关联业务表,即使区间内没有数据,也会返回0,符合你的示例要求。 - 避免重复分组:基于预先构造的时间段维度分组,而不是直接对业务数据的日期分组,从根源上解决重复结果问题。
使用注意
- 将
your_table替换为你的业务表名,your_date_column替换为存储日期的字段名。 - 调整
generate_series中的起止日期,匹配你需要统计的时间范围。
内容的提问来源于stack exchange,提问作者Deep Patel
相关产品推荐
相关产品推荐

