SQL如何生成月度统计列?实现数据透视分组统计
SQL行转列统计实现指引
你不需要用FOR循环,SQL里处理这种将日期月份转为列、统计每个Thing对应月份记录数的需求,常用两种方法:条件聚合和PIVOT语法,下面分别说明:
方法一:条件聚合(兼容性强,适合新手)
这是最通用的写法,几乎所有数据库都支持。核心思路是按Thing分组,用CASE语句判断每条记录的月份,再用聚合函数统计符合条件的数量。
假设你的表名为things_table,示例代码(以MySQL为例,其他数据库仅日期格式化函数有差异):
SELECT Thing, COUNT(CASE WHEN DATE_FORMAT(Date, '%Y-%m') = '2022-11' THEN 1 END) AS `2022-11`, COUNT(CASE WHEN DATE_FORMAT(Date, '%Y-%m') = '2022-12' THEN 1 END) AS `2022-12` FROM things_table GROUP BY Thing ORDER BY Thing;
代码说明:
DATE_FORMAT(Date, '%Y-%m'):把日期转为YYYY-MM格式的月份字符串(不同数据库写法不同:PostgreSQL用DATE_TRUNC('month', Date)::date,SQL Server用FORMAT(Date, 'yyyy-MM'))CASE语句:判断当前记录的月份是否匹配目标月份,匹配则返回1,不匹配返回NULLCOUNT():只统计非NULL值的数量,不匹配的记录自然会被统计为0GROUP BY Thing:按Thing分组,确保每个Thing只返回一行统计结果
方法二:PIVOT语法(简洁但数据库有差异)
部分数据库(如SQL Server、Oracle、PostgreSQL)支持PIVOT关键字,可以直接将行数据转为列,写法更简洁。
以SQL Server为例的示例代码:
SELECT Thing, [2022-11], [2022-12] FROM ( -- 先子查询提取Thing和格式化后的月份 SELECT Thing, FORMAT(Date, 'yyyy-MM') AS Month FROM things_table ) AS SourceTable -- 用PIVOT将Month的不同值转为列,统计数量 PIVOT ( COUNT(Month) FOR Month IN ([2022-11], [2022-12]) ) AS PivotTable ORDER BY Thing;
代码说明:
- 子查询先把原始数据处理成
Thing和Month两列 PIVOT子句指定用COUNT聚合,将Month列的不同值(2022-11、2022-12)转为单独的列,自动完成统计
内容的提问来源于stack exchange,提问作者SkreeScroll
相关产品推荐
相关产品推荐

