在特定的薪水期(“分组”)中,员工(“ Empid”)的加班时间分布在5周内(“ YearWeek”)。员工最多可以要求累积加班。
我需要在新列“ OT30_NT”和“ OT50_NT”中获得最多20个小时的总计20小时。
输入数据下面:
empid
组
Comments | 248 | G15 | 202449 | ||
---|---|---|---|---|---|
248 | G15 | 202450 | 8 | ||
在这里实现20个小时的玛克斯 | 202451 | ||||
empid |
Comments
SELECT
m.[EmployeeId]
,m.[Grouping]
,m.[GroupingForOrder]
,m.[Metric]
,m.RowNo
,m.Value
,SUM([Value]) OVER (PARTITION BY [EmployeeID], [Grouping] ORDER BY RowNo) AS 'OTCum'
,CASE
WHEN SUM([Value]) OVER (PARTITION BY [EmployeeID], [Grouping] ORDER BY RowNo)<=20 THEN Value
ELSE 20-SUM([Value]) OVER (PARTITION BY [EmployeeID], [Grouping] ORDER BY RowNo) END AS CalcAttempt
FROM
-- Second Query to add Row Numbers to get the correct Cumulative Value
(
SELECT
[EmployeeId]
,[Grouping]
,[GroupingForOrder]
,[Metric]
,[Value]
,ROW_NUMBER() OVER (PARTITION BY EMployeeID, Grouping ORDER BY GroupingForOrder) AS 'RowNo'
FROM
(
-- Initial query to pivot OT30 and OT50 Values
SELECT [EmployeeId]
,[Grouping]
,[GroupingForOrder]
,[OT30]
,[OT50]
FROM [lookups].[Timekeeping_WeeklyBreakdown]
) AS SourceTable
UNPIVOT
(Value for Metric IN (
[OT30]
,[OT50]
)) AS ALIAS
)AS m
3 | ||||
---|---|---|---|---|
G15 | 8 | 9 | ||
248 | G15 0 | 0 (所有其他值应为零) | ||
G15 | 0 | 0 | ||
G15 | 0 | 0 | ||
unpivot表可将“ OT30”和“ OT50”列转换为行(最终以“公制”和“值”) | 添加了一个rownumber列以获取适当的累积总和(最终以“ Rowno”列最终使用,将按 /顺序按子句 /顺序使用) | 通过使用“ otcum”列的“分区”条款来确定最大值的最大值20小时的位置) |
Comments
c.CumulativeOT <= @max_hours
:max_hours大于累积的全额量额定量。
G15 | OT30 | 1 | 3 | 3 | 3 | ||
---|---|---|---|---|---|---|---|
ot50 | 2 | 0 | 3 | 0 | 248 | ||
OT30 | 3 | 8 | 11 | 8 | 248 | ||
ot50 | 4 | 10 | 21 | -1应该是9(3+0+8+9 = 20) | |||
G15 | OT30 | 5 | 8 | 29 | 应为0(累积值超过20小时) | ||
G15 | ot50 | 6 | 24 | 53 | 应该是0 | ||
G15 | OT30 | 7 | 8 | 61 | 应该是0 | ||
G15 | ot50 | 8 | 2 | 63 | 应该是0 | ||
G15 | OT30 | 9 | 0 | 63 | 应该是0 | ||
G15 | ot50 | 10 | 0 | 63 | 应该是0 | ||
如果我可以根据上述注释获得“ calcattempt”列的工作,那么我可以通过'termric'转移并最终计算。 当然,假设还有另一个解决方案不需要我做以上的问题。 | unpivotot | 估计累积总和 cases表达式以确定可声称的ot值。 logic:- |
c.CumulativeOT - c.OT <= @max_hours
c.CumulativeOT - c.OT
@max_hours - c.CumulativeOT + c.OT
declare @max_hours int = 20; -- Max 20 hours
with cte as
(
select EmpID, [Grouping], [YearWeek], Seq, OT30, OT50, OT,
-- Calculate cumulative sum of OT
CumulativeOT = sum(OT) over (partition by EmpID, [Grouping]
order by [YearWeek], Seq)
from YourTable t
cross apply -- Unpivot OT30 & OT50
(
values (1, OT30), (2, OT50)
) o (seq, OT)
),
cte2 as
(
select *,
ClaimableOT = case when c.CumulativeOT <= @max_hours
then c.OT
when c.CumulativeOT - c.OT <= @max_hours
then @max_hours - c.CumulativeOT + c.OT
else 0
end
from cte c
)
-- Pivot back the OT column
select EmpID, [Grouping], YearWeek,
OT30, OT50, -- original OT value
ClaimableOT30 = SUM(case when seq = 1 then ClaimableOT else 0 end),
ClaimableOT50 = SUM(case when seq = 2 then ClaimableOT else 0 end)
from cte2
group by EmpID, [Grouping], YearWeek, OT30, OT50
order by EmpID, [Grouping], YearWeek;