You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server按周一零点截断跨周班次 统计员工周工作时长

周度员工工时统计实现方案

需求规则

需基于Bookings表统计员工周度总工作时长,统计规则如下:

  • 周度时间边界:每周一零点至下一周周一零点
  • 跨边界排班处理:排班记录跨周边界时,需按边界时间截断后,再计算落在统计周期内的有效时长

基础信息

表结构与测试数据

create table Bookings (ID int IDENTITY(1,1) not null, start datetime, finish datetime, staffId int)

insert into Bookings (start, finish, staffId) values ('2022-06-19 21:00:00', '2022-06-20 07:00:00', 1)
insert into Bookings (start, finish, staffId) values ('2022-06-24 21:00:00', '2022-06-25 07:00:00', 1)
insert into Bookings (start, finish, staffId) values ('2022-06-25 21:00:00', '2022-06-26 07:00:00', 1)
insert into Bookings (start, finish, staffId) values ('2022-06-26 21:00:00', '2022-06-27 07:00:00', 1)

初始查询的错误点

初始查询未做跨边界截断,直接按排班原始时长计算:

select *, datediff(MINUTE, start, finish)/60.0
from Bookings
where staffid = 1 and start between '2022-06-19' and '2022-06-27'

查询结果示例
针对2022-06-20(周一)至2022-06-27(周一)的统计周期,初始查询返回总时长40小时,不符合业务要求:

  • 第一条记录(2022-06-19 21:00至2022-06-20 07:00)跨周起始边界,有效起始时间应为2022-06-20 00:00,有效工时7小时,原始计算多算3小时
  • 第四条记录(2022-06-26 21:00至2022-06-27 07:00)跨周结束边界,有效结束时间应为2022-06-27 00:00,有效工时3小时,原始计算多算7小时
  • 中间两条记录完全落在统计周期内,每条有效工时10小时,周期内正确总工时应为30小时。

正确实现代码(SQL Server)

核心思路:先计算每条排班记录对应周的起止边界,再对排班时间做截断,取排班时间和周边界的交集作为有效计算区间,最后汇总时长。

WITH BookingWithWeek AS (
    SELECT
        *,
        -- 计算排班所在周的周一零点,兼容@@DATEFIRST环境配置
        DATEADD(DAY, 1 - (DATEPART(WEEKDAY, start) + @@DATEFIRST - 2) % 7, CAST(start AS DATE)) AS week_start,
        -- 计算对应周的结束点(下周一零点)
        DATEADD(DAY, 8 - (DATEPART(WEEKDAY, start) + @@DATEFIRST - 2) % 7, CAST(start AS DATE)) AS week_end
    FROM Bookings
    WHERE staffId = 1
)
SELECT
    staffId,
    week_start AS stat_week_start,
    week_end AS stat_week_end,
    SUM(
        DATEDIFF(
            MINUTE,
            -- 有效开始时间:取排班开始时间、周开始时间的较晚值
            CASE WHEN start > week_start THEN start ELSE week_start END,
            -- 有效结束时间:取排班结束时间、周结束时间的较早值
            CASE WHEN finish < week_end THEN finish ELSE week_end END
        ) / 60.0
    ) AS total_valid_hours
FROM BookingWithWeek
-- 指定要统计的周起始时间即可,示例统计2022-06-20开始的周
WHERE week_start = '2022-06-20'
GROUP BY staffId, week_start, week_end

逻辑说明

  • 周起始计算兼容SQL Server的@@DATEFIRST设置,不会因为环境星期起始配置不同导致周一计算错误
  • 截断逻辑自动适配三种排班场景:完全在周内、跨周起始、跨周结束,不需要额外写复杂分支判断
  • 运行上述测试数据,将返回正确结果:总有效工时30小时。

内容的提问来源于stack exchange,提问作者Dan Williams

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:21:21