那就好!这是一个有趣的挑战,我非常高兴,因为我破解了它。注释等在代码注释中。如果您想更改可累积奖金的天数,请更改@DaysInBonusPeriod
中的值。这也适用于多个AgentID
秒和日期的任何序列,假设其中的任何缺少的日期不包括奖金计提时期 - 即:如果你忽视周日和周三时段进行计数:
Day Period Day
Monday 1
Tuesday 2
Thursday 3
Friday 4
Saturday 5
Monday 6
解决方案
declare @t table(AgentID int
,DateValue Date
,Sales int
);
insert into @t
select 1,'2016-10-31',1 union all
select 1,'2016-11-01',2 union all
select 1,'2016-11-02',1 union all
select 1,'2016-11-03',5 union all
select 1,'2016-11-04',3 union all
select 1,'2016-11-05',2 union all
select 1,'2016-11-07',6 union all
select 1,'2016-11-08',5 union all
select 1,'2016-11-09',4 union all
select 1,'2016-11-10',6 union all
select 1,'2016-11-11',1 union all
select 1,'2016-11-12',3 union all
select 1,'2016-11-14',2 union all
select 1,'2016-11-15',2 union all
select 1,'2016-11-16',4 union all
select 1,'2016-11-17',2 union all
select 1,'2016-11-18',2 union all
select 2,'2016-10-31',1 union all
select 2,'2016-11-01',7 union all
select 2,'2016-11-02',0 union all
select 2,'2016-11-03',0 union all
select 2,'2016-11-04',0 union all
select 2,'2016-11-05',0 union all
select 2,'2016-11-07',0 union all
select 2,'2016-11-08',0 union all
select 2,'2016-11-09',1 union all
select 2,'2016-11-10',3 union all
select 2,'2016-11-11',2 union all
select 2,'2016-11-12',3 union all
select 2,'2016-11-14',7 union all
select 2,'2016-11-15',6 union all
select 2,'2016-11-16',3 union all
select 2,'2016-11-17',5 union all
select 2,'2016-11-18',3;
-- Set the number of days that sales can accrue towards a Bonus.
declare @DaysInBonusPeriod int = 6;
with rn -- Derived table to get incremental ordering for recursice cte. This is useful as Sundays are ignored.
as
(
select t.AgentID
,t.DateValue
,t.Sales
,row_number() over (order by t.AgentID, t.DateValue) as rn
from @t t
)
,prev -- Using the row numbering above, find the number of sales in the day before the bonus accrual period. We have to use the row numbers as Sundays are ignored.
as
(
select t.AgentID
,t.DateValue
,t.Sales
,t.rn
,isnull(tp.Sales,0) as SalesOnDayBeforeCurrentPeriod
from rn t
left join rn tp
on(t.AgentID = tp.AgentID
and tp.rn = t.rn - @DaysInBonusPeriod -- Get number of sales on the day before the max Bonus period.
)
)
,cte -- Use a recursive cte to calculate running totals based on sales, whether the bonus was achieved the previous day and if the previous bonus was more than 5 days ago.
as
(
select rn
,AgentID
,DateValue
,Sales
,SalesOnDayBeforeCurrentPeriod
,Sales as TotalSales
,case when Sales >= 15 then 1 else 0 end as Bonus
,1 as DaysSinceLastBonus
from prev
where rn = 1 -- Select just the first row in the dataset.
union all
select t.rn
,t.AgentID
,t.DateValue
,t.Sales
,t.SalesOnDayBeforeCurrentPeriod
-- If the previous row was for the same agent and not a bonus, add the day's sales to the total, subtracting the sales from the day before the 6 day bonus period if it has been more than 6 days since the last bonus.
,case when t.AgentID = c.AgentID
then case when c.Bonus = 0
then t.Sales + c.TotalSales - case when c.DaysSinceLastBonus >= @DaysInBonusPeriod then t.SalesOnDayBeforeCurrentPeriod else 0 end
else t.Sales
end
else t.Sales
end as TotalSales
-- If the value in the TotalSales field above is 15 or more, flag a bonus.
,case when
case when t.AgentID = c.AgentID --\
then case when c.Bonus = 0 -- \
then t.Sales + c.TotalSales - case when c.DaysSinceLastBonus >= @DaysInBonusPeriod then t.SalesOnDayBeforeCurrentPeriod else 0 end -- \ Same statement
else t.Sales --/as TotalSales
end --/
else t.Sales --/
end >= 15
then 1
else 0
end as Bonus
-- If there is no flag in Bonus field above, increment the number of days since the last bonus.
,case when
case when --\
case when t.AgentID = c.AgentID -- \
then case when c.Bonus = 0 -- |
then t.Sales + c.TotalSales - case when c.DaysSinceLastBonus >= @DaysInBonusPeriod then t.SalesOnDayBeforeCurrentPeriod else 0 end -- |
else t.Sales -- \ Same statement
end --/as Bonus
else t.Sales -- |
end >= 15 -- |
then 1 --/
else 0 --/
end = 0
then c.DaysSinceLastBonus + 1
else 0
end as DaysSinceLastBonus
from prev t
inner join cte c
on(t.rn = c.rn+1)
)
select AgentID
,DateValue
,Sales
,TotalSales
,Bonus
from cte
order by rn
option (maxrecursion 0);
你有你至今尝试过的脚本? – iamdave
另外,同一天15日之后的销售额是否会计入下一个目标?因此,如果他们在第1天售出14,然后在第2天售出3,那么对第3天的第2个或第2个目标开始计数? – iamdave
哦,还有(!)是否每个代理每天最多只有一条记录? – iamdave