如何按日期展示员工工作时长?SQL查询格式化及求和求助
解决SQL行转列+时长总和的方案
嘿,我来帮你搞定这个表格填充的问题!从你的描述来看,核心需求就是把日期对应的时长数据映射到每周的对应天数列中,同时还要计算总时长对吧?这其实就是典型的SQL行转列场景,我给你两种实用的解决方案,适配不同的数据库环境:
方法一:条件聚合(兼容性最强,适合所有SQL数据库)
这种方法用CASE WHEN配合SUM函数,把每一天的时长单独计算出来,兼容性拉满,不管是SQL Server、MySQL还是PostgreSQL都能用。
假设你的原数据是类似日期和时长的结构,那可以这么写:
SELECT -- 替换成你实际需要的分组字段,比如员工ID、项目名称等 员工ID, 项目名称, -- 按星期几拆分时长,这里以SQL Server为例,注意不同数据库的星期函数略有不同 SUM(CASE WHEN DATENAME(dw, 日期) = 'Monday' THEN 时长 ELSE 0 END) AS 周一, SUM(CASE WHEN DATENAME(dw, 日期) = 'Tuesday' THEN 时长 ELSE 0 END) AS 周二, SUM(CASE WHEN DATENAME(dw, 日期) = 'Wednesday' THEN 时长 ELSE 0 END) AS 周三, SUM(CASE WHEN DATENAME(dw, 日期) = 'Thursday' THEN 时长 ELSE 0 END) AS 周四, SUM(CASE WHEN DATENAME(dw, 日期) = 'Friday' THEN 时长 ELSE 0 END) AS 周五, SUM(CASE WHEN DATENAME(dw, 日期) = 'Saturday' THEN 时长 ELSE 0 END) AS 周六, SUM(CASE WHEN DATENAME(dw, 日期) = 'Sunday' THEN 时长 ELSE 0 END) AS 周日, -- 计算总时长 SUM(时长) AS 总时长 FROM 你的数据表名 -- 可选:过滤指定周的日期,比如只查2024年第20周的数据 WHERE DATEPART(week, 日期) = 20 AND YEAR(日期) = 2024 GROUP BY 员工ID, 项目名称 -- 按你的业务维度分组
适配不同数据库的小调整:
- MySQL:把
DATENAME(dw, 日期)换成DAYNAME(日期),比如DAYNAME(日期) = 'Monday' - PostgreSQL:用
TO_CHAR(日期, 'FMDay') = 'Monday'(FMDay会去掉多余空格) - 如果想按数字判断星期(避免语言差异),比如SQL Server用
DATEPART(dw, 日期)(1=周日,2=周一),MySQL用DAYOFWEEK()(1=周日,2=周一),PostgreSQL用EXTRACT(DOW FROM 日期)(0=周日,1=周一)
方法二:PIVOT函数(适合SQL Server、Oracle等支持的数据库)
如果你的数据库支持PIVOT语法,写法会更简洁:
SELECT 员工ID, 项目名称, [Monday] AS 周一, [Tuesday] AS 周二, [Wednesday] AS 周三, [Thursday] AS 周四, [Friday] AS 周五, [Saturday] AS 周六, [Sunday] AS 周日, 总时长 FROM ( SELECT 员工ID, 项目名称, DATENAME(dw, 日期) AS 星期几, 时长, -- 用窗口函数提前计算每组的总时长 SUM(时长) OVER (PARTITION BY 员工ID, 项目名称) AS 总时长 FROM 你的数据表名 WHERE DATEPART(week, 日期) = 20 AND YEAR(日期) = 2024 ) AS 源数据表 PIVOT ( SUM(时长) -- 这里要和子查询里的星期几取值完全匹配 FOR 星期几 IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday]) ) AS 透视表
后续前端填充提示
拿到这样的查询结果后,你的Ajax回调里就可以直接把每一行的周一、周二...总时长字段对应填充到HTML表格的列中,完全不用再在前端做复杂的计算啦!
内容的提问来源于stack exchange,提问作者Tony Batista
相关产品推荐
相关产品推荐

