如何编写SQL实现按日期分桶统计且每个日期为单独列
多日期余额分桶列转统计实现方案
使用条件聚合即可实现单查询返回多日期分列的统计结果,兼容MySQL、Hive、SparkSQL等绝大多数主流SQL引擎,且仅需扫描一次指定日期范围的数据,性能优于多次单日期查询。
实现逻辑:
- 保留原有的余额分桶
CASE判断逻辑,作为全局分组维度 - 针对每个需要统计的日期,使用
COUNT(CASE WHEN 日期匹配 THEN user_id END)的写法,单独统计该日期下对应分桶的用户数,每个日期对应独立一列 WHERE条件中限定所有需要统计的日期范围,避免无效全表扫描- 最终按余额分桶字段分组、排序即可
参考SQL(示例统计3天数据,需要新增日期时按相同格式追加列即可):
SELECT CASE WHEN balance_chips_end <= 750 THEN '< 750' WHEN balance_chips_end > 750 AND balance_chips_end <= 1250 THEN 'A. 750-1250' WHEN balance_chips_end > 1250 AND balance_chips_end <= 2750 THEN 'B. 1250-2750' WHEN balance_chips_end > 2750 AND balance_chips_end <= 5000 THEN 'C. 2750-5000' WHEN balance_chips_end > 5000 AND balance_chips_end <= 10000 THEN 'D. 5000-10000' WHEN balance_chips_end > 10000 AND balance_chips_end <= 20000 THEN 'E. 10000-20000' WHEN balance_chips_end > 20000 AND balance_chips_end <= 40000 THEN 'F. 20000-40000' ELSE 'G. > 40000' END AS balance_bucket, COUNT(CASE WHEN event_day_pst = '2022-06-11' THEN user_id END) AS `2022-06-11`, COUNT(CASE WHEN event_day_pst = '2022-06-12' THEN user_id END) AS `2022-06-12`, COUNT(CASE WHEN event_day_pst = '2022-06-13' THEN user_id END) AS `2022-06-13` FROM table1 WHERE event_day_pst IN ('2022-06-11','2022-06-12','2022-06-13') -- 替换为实际需要统计的日期列表 GROUP BY balance_bucket ORDER BY balance_bucket;
语法提示:日期值作为列别名时,属于SQL标识符,建议使用反引号包裹,不要使用单引号,避免出现语法错误。
如果使用BigQuery、Snowflake等支持PIVOT语法的数仓引擎,也可以用PIVOT语法实现同等效果,但上述条件聚合写法通用性更强,不需要适配不同引擎的特殊语法。
内容的提问来源于stack exchange,提问作者Atul Singh
相关产品推荐
相关产品推荐

