如何在Amazon Redshift中从指定日期开始按周分组每日数据?
在Amazon Redshift中实现按指定起始日每7天分组并输出单行格式
要实现你需要的效果,可以分成两个核心步骤:按自定义7天周期分组统计数据,再将分组结果拼接成要求的单行格式。下面是具体的实现方案:
1. 基础实现(仅统计有数据的分组)
如果只需要统计存在数据的7天组,可以用以下SQL:
SELECT 'counts ' || LISTAGG(CONCAT(group_start_date::VARCHAR, ' ', cnt::VARCHAR), ' ') WITHIN GROUP (ORDER BY group_start_date) AS result FROM ( -- 子查询:计算每个数据行所属的7天组起始日期,并统计每组数量 SELECT DATEADD(day, (DATEDIFF(day, '2017-11-27'::DATE, your_date_column) / 7) * 7, '2017-11-27'::DATE) AS group_start_date, COUNT(*) AS cnt FROM your_table -- 替换成你的表名 WHERE your_date_column >= '2017-11-27'::DATE AND your_date_column <= '2017-12-18'::DATE -- 替换成你的指定结束日期 GROUP BY group_start_date ) grouped_data;
关键逻辑说明:
- 分组起始日期计算:
DATEADD(day, (DATEDIFF(day, '2017-11-27', your_date_column)/7)*7, '2017-11-27')会把每个日期映射到离它最近的、不晚于它的2017-11-27开始的7天组起始日(比如2017-11-28会被分到2017-11-27组,2017-12-04分到2017-12-04组)。 - 拼接成单行:用
LISTAGG函数把每个组的「日期+数量」字符串按顺序拼接,再加上开头的counts。
2. 进阶实现(包含无数据的分组,显示count为0)
如果需要显示所有7天组(即使该组没有数据,count显示为0),可以先生成完整的日期序列,再左连接统计数据:
WITH date_series AS ( -- 递归CTE生成从2017-11-27开始的所有7天组起始日期 SELECT '2017-11-27'::DATE AS group_start_date UNION ALL SELECT DATEADD(day, 7, group_start_date) FROM date_series WHERE group_start_date < '2017-12-18'::DATE -- 替换成你的指定结束日期 ) SELECT 'counts ' || LISTAGG(CONCAT(ds.group_start_date::VARCHAR, ' ', COALESCE(t.cnt, 0)::VARCHAR), ' ') WITHIN GROUP (ORDER BY ds.group_start_date) AS result FROM date_series ds LEFT JOIN ( -- 子查询:同基础实现的统计逻辑 SELECT DATEADD(day, (DATEDIFF(day, '2017-11-27'::DATE, your_date_column) / 7) * 7, '2017-11-27'::DATE) AS group_start_date, COUNT(*) AS cnt FROM your_table WHERE your_date_column >= '2017-11-27'::DATE AND your_date_column <= '2017-12-18'::DATE GROUP BY group_start_date ) t ON ds.group_start_date = t.group_start_date;
关键补充:
- 递归CTE生成日期序列:
date_series会自动生成所有从起始日到结束日的7天组起始日期,确保每个周期都被包含。 - COALESCE处理空值:用
COALESCE(t.cnt, 0)把没有数据的组的count设为0,避免出现空值。
这两种方案都能输出你需要的格式,比如你示例中的counts 2017-11-27 100 2017-12-04 200 2017-12-11 300 2017-12-18 400。
内容的提问来源于stack exchange,提问作者Liondancer
相关产品推荐
相关产品推荐

