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

如何在Teradata中按月份统计员工休假时长(排除周末并精准分摊)

按工作日分摊跨月休假时长的解决方案

看起来你需要把员工的总休假时长按所有涉及的工作日平均分摊到对应月份,我来给你一个基于日历表的具体实现方案,刚好能匹配你想要的结果:

核心思路

  1. 先筛选出员工所有休假记录覆盖的工作日(排除周末/节假日)
  2. 计算该员工的总休假时长,以及这些休假涉及的总工作日数量
  3. 把总时长按每个工作日平均分摊,再按月份汇总得到各月的分摊时长

具体SQL实现

假设你的休假记录表叫LeaveRecords,日历表叫Calendar,先确认表结构:

  • LeaveRecords:EmployeeID(员工ID)、BeginDate(休假开始日)、EndDate(休假结束日)、TotalHours(该段休假总时长)
  • Calendar:Date(日期)、IsWorkday(是否工作日,1=是,0=否)、YearMonth(年月,格式如'2017-10')

分步查询实现

-- 第一步:找出该员工所有休假涉及的工作日
WITH AllLeaveWorkdays AS (
    SELECT
        lr.EmployeeID,
        c.Date,
        c.YearMonth
    FROM LeaveRecords lr
    JOIN Calendar c 
        ON c.Date BETWEEN lr.BeginDate AND lr.EndDate
    WHERE 
        c.IsWorkday = 1 -- 只保留工作日
        AND lr.EmployeeID = 168835 -- 可根据需要移除,支持批量员工
),
-- 第二步:计算总休假时长和总工作日数
TotalStats AS (
    SELECT
        EmployeeID,
        SUM(lr.TotalHours) AS TotalLeaveHours,
        COUNT(DISTINCT alwd.Date) AS TotalWorkdays
    FROM LeaveRecords lr
    JOIN AllLeaveWorkdays alwd 
        ON lr.EmployeeID = alwd.EmployeeID
    GROUP BY EmployeeID
)
-- 第三步:按月份汇总分摊后的时长
SELECT
    alwd.EmployeeID,
    alwd.YearMonth,
    ROUND(SUM(ts.TotalLeaveHours / ts.TotalWorkdays), 2) AS AllocatedHours
FROM AllLeaveWorkdays alwd
JOIN TotalStats ts 
    ON alwd.EmployeeID = ts.EmployeeID
GROUP BY alwd.EmployeeID, alwd.YearMonth
ORDER BY alwd.EmployeeID, alwd.YearMonth;

结果验证

针对你的示例数据:

  • 总休假时长:32+6=38小时
  • 总工作日数:9天(10月31日1天 + 11月的8天)
  • 每个工作日分摊时长:38/9≈4.22小时
  • 10月分摊:1×4.22=4.22小时
  • 11月分摊:8×4.22≈33.76,四舍五入后为33.77小时,和你的预期完全匹配

注意事项

  1. 确保日历表的IsWorkday字段准确标记了所有非工作日(包括周末和公司自定义节假日)
  2. 如果需要批量处理所有员工,只需移除AllLeaveWorkdays中的AND lr.EmployeeID = 168835条件
  3. 可以通过调整ROUND函数的第二个参数来控制小数位数,比如保留两位就用ROUND(..., 2)

内容的提问来源于stack exchange,提问作者Gurpreet Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:42:24