如何动态将行值转为表头并按年月汇总员工入职人数
按年月统计员工入职人数并转置为表头的实现方案
嘿,针对你这个按年月统计入职人数并把年月设为表头的需求,我整理了对应的实现方法,先从咱们手上的数据源说起:
现有EMPLOYEE表数据
咱们的EMPLOYEE表包含EMP_NAME(员工姓名)和EMP_DOJ(入职日期)两个字段,具体数据如下:
| EMP_NAME | EMP_DOJ |
|---|---|
| Ramesh | 10-jan-2017 |
| Sandeep | 09-jan-2017 |
| Bhaskar | 11-feb-2017 |
| Jyoti | 12-mar-2017 |
| Rohan | 12-mar-2017 |
| Kadali | 11-feb-2018 |
| Kumari | 12-mar-2018 |
| Salvi | 12-mar-2018 |
需求明确
需要按年月统计每个时段的入职员工人数,并且把年月(格式如JAN17、FEB17)作为表头列,最终输出如下格式的结果:
| JAN17_COUNT | FEB17_COUNT | MAR17_COUNT | FEB18_COUNT | MAR18_COUNT |
|---|---|---|---|---|
| 2 | 1 | 2 | 1 | 2 |
实现方案
这里提供两种常用的SQL写法,适配不同数据库环境:
方法一:通用条件聚合(兼容大多数数据库)
这种写法不依赖数据库特定的PIVOT函数,用CASE WHEN配合COUNT就能实现列转行:
SELECT COUNT(CASE WHEN TO_CHAR(EMP_DOJ, 'MONRR') = 'JAN17' THEN 1 END) AS JAN17_COUNT, COUNT(CASE WHEN TO_CHAR(EMP_DOJ, 'MONRR') = 'FEB17' THEN 1 END) AS FEB17_COUNT, COUNT(CASE WHEN TO_CHAR(EMP_DOJ, 'MONRR') = 'MAR17' THEN 1 END) AS MAR17_COUNT, COUNT(CASE WHEN TO_CHAR(EMP_DOJ, 'MONRR') = 'FEB18' THEN 1 END) AS FEB18_COUNT, COUNT(CASE WHEN TO_CHAR(EMP_DOJ, 'MONRR') = 'MAR18' THEN 1 END) AS MAR18_COUNT FROM EMPLOYEE;
注意:
TO_CHAR是Oracle/PostgreSQL等数据库的写法,如果是MySQL,需要换成DATE_FORMAT(STR_TO_DATE(EMP_DOJ, '%d-%b-%Y'), '%b%y')——先把字符串转成日期类型,再格式化年月。
方法二:Oracle专用PIVOT函数
如果你的数据库是Oracle,可以用更简洁的PIVOT语法:
SELECT * FROM ( SELECT TO_CHAR(EMP_DOJ, 'MONRR') AS MONTH_YEAR FROM EMPLOYEE ) PIVOT ( COUNT(*) FOR MONTH_YEAR IN ( 'JAN17' AS JAN17_COUNT, 'FEB17' AS FEB17_COUNT, 'MAR17' AS MAR17_COUNT, 'FEB18' AS FEB18_COUNT, 'MAR18' AS MAR18_COUNT ) );
代码解释
- 年月格式转换:用日期格式化函数把入职日期转换成
MONRR格式(比如10-jan-2017转成JAN17),统一按年月维度分组。 - 统计逻辑:
- 方法一中,每个
CASE WHEN判断当前行的年月是否匹配目标值,匹配则返回1,否则返回NULL,COUNT会自动忽略NULL值,从而得到对应年月的入职人数。 - 方法二中,先通过子查询提取所有年月,再用PIVOT函数直接把行转成列并统计数量,语法更简洁直观。
- 方法一中,每个
内容的提问来源于stack exchange,提问作者user1463065
相关产品推荐
相关产品推荐

