SQL如何按成本中心统计各月员工特定原因上报工时总和且无需固定日期
核心实现思路
不用写多个UNION分支,用条件聚合的思路,通过CASE判断每行数据所属月份,再对对应月份的工时求和即可,天然支持动态取当前运行时间对应的年度数据,不需要写死日期。
通用SQL实现示例(适配大部分SQL方言,特殊日期函数可根据你用的数据库微调)
SELECT CostCentre, -- 1月求和 SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATE_TRUNC('year', CURRENT_DATE) THEN hours ELSE 0 END) AS January, -- 2月求和 SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 1, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS February, -- 3月到12月以此类推,复制修改月份偏移量即可 SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 2, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS March, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 3, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS April, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 4, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS May, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 5, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS June, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 6, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS July, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 7, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS August, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 8, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS September, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 9, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS October, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 10, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS November, SUM(CASE WHEN DATE_TRUNC('month', Fromdate) = DATEADD('month', 11, DATE_TRUNC('year', CURRENT_DATE)) THEN hours ELSE 0 END) AS December FROM Transaction -- 筛选当前自然年的所有数据 WHERE Fromdate >= DATE_TRUNC('year', CURRENT_DATE) AND Fromdate < DATEADD('year', 1, DATE_TRUNC('year', CURRENT_DATE)) -- 你可以在这里加你需要的「特定原因」过滤条件,比如 Reason = 'xxx' GROUP BY CostCentre ORDER BY CostCentre;
常见数据库方言适配说明
如果你的数据库是MySQL、SQL Server这类,调整日期函数即可:
- MySQL:把
DATE_TRUNC('month', 日期)换成DATE_FORMAT(日期, '%Y-%m-01'),CURRENT_DATE换成CURDATE(),DATEADD('month', 偏移量, 日期)换成DATE_ADD(日期, INTERVAL 偏移量 MONTH) - SQL Server:把
DATE_TRUNC('year', CURRENT_DATE)换成DATEFROMPARTS(YEAR(GETDATE()), 1, 1),DATEADD参数顺序调整为DATEADD(MONTH, 偏移量, 日期)
动态列扩展(如果需要自动生成列名适配不同年份,不需要手动写12个月的列)
如果你用的是支持动态SQL的数据库(比如PostgreSQL、SQL Server、MySQL都支持),可以写存储过程拼接SQL字符串,执行后直接返回带对应年份月份列名的结果,完全不需要手动修改代码。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

