我正在研究一个看似相当复杂的MS-SQL报告。
在公司中有一条规则规定,如果员工没有将这些时间作为空闲时间,那么人们加班时间应在30天后(在下一个工资单上)自动支付。
报告必须包含一个列表,其中包含下一个工资单上剩余的加班时间。
计算将消耗最新的小时数。
这是员工加班时间的清单(为了这个例子,只有一名员工)
person_ID OvertimeHourDate OVTHoursMade
123123 15.02.2017 2
123123 17.02.2017 4
123123 19.02.2017 2
123123 21.02.2017 2
123123 23.02.2017 5
123123 25.02.2017 5
123123 28.02.2017 7
123123 15.03.2017 7
123123 17.03.2017 8
123123 21.03.2017 6
123123 23.03.2017 8
123123 25.03.2017 5
123123 27.03.2017 8
123123 29.03.2017 6
例如,如果该员工没有休假,则2017年2月15日起的2小时将在30天后自动支付(更确切地说是紧随其后的工资单31.03.2017);下一行也一样。
这是空闲时间的列表。
person_ID Date Hours Off Taken
158223 22.02.2017 8
158223 24.02.2017 7
从前3行(最早的日期)中减去8小时的时间:2 + 4 + 2
person_ID OvertimeHourDate OVTHoursMade
123123 15.02.2017 2
123123 17.02.2017 4
123123 19.02.2017 2
7小时由以下以下行计算:2 + 5
person_ID OvertimeHourDate OVTHoursMade
123123 21.02.2017 2
123123 23.02.2017 5
最终报告应如下所示
person_ID Overtime Hours Remaining To Be Paid Until Next Payroll on 31.03.2017
158223 12
所以这12小时计算如下: 由于消费了以下日期之前的几个小时,我们将仅考虑以下因素:
25.02.2017 5h
28.02.2017 7h
之后的日子没有考虑在内,因为日期超过了当前的工资单,他们将在下一个工资单上支付(31.04.2017)
看起来很复杂,我真的需要你的建议。
先谢谢你们!
答案 0 :(得分:0)
如果你想每天都这样做,那么你可以将这样的日子和加班时间结合在一起,看看“总”CTE,其中包括人格,日期和加班时间以及工会与人格,日期和负面工作时间。
set dateformat DMY
;with overtime as
(
select
*
from
(
values
(123123, cast('15.02.2017' as date),2)
,(123123,cast('17.02.2017' as date),4)
,(123123,cast('19.02.2017' as date),2)
,(123123,cast('21.02.2017' as date),2)
,(123123,cast('23.02.2017' as date),5)
,(123123,cast('25.02.2017' as date),5)
,(123123,cast('28.02.2017' as date),7)
,(123123,cast('15.03.2017' as date),7)
,(123123,cast('17.03.2017' as date),8)
,(123123,cast('21.03.2017' as date),6)
,(123123,cast('23.03.2017' as date),8)
,(123123,cast('25.03.2017' as date),5)
,(123123,cast('27.03.2017' as date),8)
,(123123,cast('29.03.2017' as date),6)
) a(person_ID, OvertimeHourDate , OVTHoursMade))
,hoursoff as
(
select * from
(values
(123123,cast('22.02.2017' as date),8)
,(123123,cast('24.02.2017' as date),7)
) b(person_ID, Date, [Hours Off Taken]))
,total as
(
select person_ID,eomonth(OvertimeHourDate,1) eom,OvertimeHourDate [Date],OVTHoursMade [Hours] from overtime
union all
select person_ID,eomonth([date],1),[date],-[Hours Off Taken]
from hoursoff
)
select * from total
这给出了:
person_ID eom Date Hours
123123 31-03-2017 15-02-2017 2
123123 31-03-2017 17-02-2017 4
123123 31-03-2017 19-02-2017 2
123123 31-03-2017 21-02-2017 2
123123 31-03-2017 23-02-2017 5
123123 31-03-2017 25-02-2017 5
123123 31-03-2017 28-02-2017 7
123123 30-04-2017 15-03-2017 7
123123 30-04-2017 17-03-2017 8
123123 30-04-2017 21-03-2017 6
123123 30-04-2017 23-03-2017 8
123123 30-04-2017 25-03-2017 5
123123 30-04-2017 27-03-2017 8
123123 30-04-2017 29-03-2017 6
123123 31-03-2017 22-02-2017 -8
123123 31-03-2017 24-02-2017 -7
“EOM”栏是支付工资的日期。
现在,我们使用两个分析函数sum和rownumber:
代替las“select * from total”使用此:
select
person_ID
,eom
,Date
,Hours
,sum(Hours) over (partition by person_ID,eom order by date) TotHours
,row_number() over (partition by person_ID,eom order by date desc) rn
from total
order by date
这给了我们一个小时的运行总计,而rn列每个月给出一个递减的条目数,所以最后一个有rn = 1
person_ID eom Date Hours TotHours rn
123123 2017-03-31 2017-02-15 2 2 9
123123 2017-03-31 2017-02-17 4 6 8
123123 2017-03-31 2017-02-19 2 8 7
123123 2017-03-31 2017-02-21 2 10 6
123123 2017-03-31 2017-02-22 -8 2 5
123123 2017-03-31 2017-02-23 5 7 4
123123 2017-03-31 2017-02-24 -7 0 3
123123 2017-03-31 2017-02-25 5 5 2
123123 2017-03-31 2017-02-28 7 12 1
123123 2017-04-30 2017-03-15 7 7 7
123123 2017-04-30 2017-03-17 8 15 6
123123 2017-04-30 2017-03-21 6 21 5
123123 2017-04-30 2017-03-23 8 29 4
123123 2017-04-30 2017-03-25 5 34 3
123123 2017-04-30 2017-03-27 8 42 2
123123 2017-04-30 2017-03-29 6 48 1
员工工资加班时数由:
找到set dateformat DMY
;with overtime as
(
select
*
from
(
values
(123123, cast('15.02.2017' as date),2)
,(123123,cast('17.02.2017' as date),4)
,(123123,cast('19.02.2017' as date),2)
,(123123,cast('21.02.2017' as date),2)
,(123123,cast('23.02.2017' as date),5)
,(123123,cast('25.02.2017' as date),5)
,(123123,cast('28.02.2017' as date),7)
,(123123,cast('15.03.2017' as date),7)
,(123123,cast('17.03.2017' as date),8)
,(123123,cast('21.03.2017' as date),6)
,(123123,cast('23.03.2017' as date),8)
,(123123,cast('25.03.2017' as date),5)
,(123123,cast('27.03.2017' as date),8)
,(123123,cast('29.03.2017' as date),6)
) a(person_ID, OvertimeHourDate , OVTHoursMade))
,hoursoff as
(
select * from
(values
(123123,cast('22.02.2017' as date),8)
,(123123,cast('24.02.2017' as date),7)
) b(person_ID, Date, [Hours Off Taken]))
,total as
(
select person_ID,eomonth(OvertimeHourDate,1) eom,OvertimeHourDate [Date],OVTHoursMade [Hours] from overtime
union all
select person_ID,eomonth([date],1),[date],-[Hours Off Taken]
from hoursoff
)
select person_id,eom,TotHours
from
(
select
person_ID
,eom
,Date
,Hours
,sum(Hours) over (partition by person_ID,eom order by date) TotHours
,row_number() over (partition by person_ID,eom order by date desc) rn
from total
) a
where rn=1