排班思路與存儲過程--排班(一)


 /*

由於系統系統調取排班信息,所以安排系統進行排班處理
00網排班需求
1.共三個個班次,正常班,中班、中長班,中班隨機穿插在正常班中,中長班隨機穿插在中
班中。
2.CD兩個分組,每個大組分四個小組,如C1,C2,C3,C4,D1,D2,D3,D4。每日需3個中班,C組2
個中班時,D組1個中班;中班人數分配一周輪換一次。中長班班所需人數共2人,從CD組各
安排一個。
3.一個月總休息天數和當月周末數相同,當周周末有上班,只能安排在相鄰的兩個周休息。
同一人周末兩天不可連續上班。每人連續上班天數不得超過5天。
4.中長班次日必須為休息或中班。僅在附表一中人員中安排中長班(盡量均等),附表二中人
員不可安排中長班。
5.CD組同一天休息總人數不可大於3人,周末除外。
6.周末值班人數正常班4人、中班4人、中長班2人。
7.遇節假日3天休息,值班3天班次不受周六日影響,3天所上班次相同。

主站排班表需求
如果A1、A2組今天是呼入,那A3、A4組就是呼出,呼入呼出是每天輪流的,
紅人只會出現在呼出組 ,每天3人,一個月大家紅人天數均等
早班班次安排1個晚班,0個長班。中班班次安排2個晚班,3個長班。晚班及長班包括主站客
服及旺旺客服總和。
1.共四個班次,早班,中班,長中班,晚班,早中班按周輪,周日到下周六為一輪,晚班隨
機穿插在早中班。
2.AB兩個分組,每個大組分四個小組,如A1,A2,A3,A4,B1,B2,B3,B4。A組上早班時,B組上中
班,晚班所需人數共N人(N可自行設定),從AB組各安排一半,非雙數時中班安排多一個。
3.一個月總休息天數和當月周末數相同,當周周末有上班,只能安排在相鄰的兩個周休息。
同一人周末兩天不可連續上班。
4.晚班次日必須為休息,長晚班次日必須為晚班或休息。僅在附表一中人員中安排長晚班(
盡量均等),附表二中人員不可安排長晚班,非附表一中其他人員晚班數要求盡量均等。
5.1,2小組同一天休息人數不可大於大組人數的1/4,周末除外。3,4小組同樣要求。
6.周末值班人數可自行設定。
7.遇節假日3天休息,A組3天班次不受周六日影響,3天所上班次相同。
a.根據周進行AB組早中班交替,之前有排班記錄的,要接上之前最后周的來交替
b.計算每個人早中晚班上班數量,紅人等屬性(屬性可以后續加)

*/

 

declare @yearmonth int
set @yearmonth=11
delete tbCustomerScheduled where yearmonth=@yearmonth

declare @maxleave int
set @maxleave=4--設置每天最大休息人數為總人數的 1/@maxleave
declare @from date
declare @end date
declare @date date
declare @i int
declare @count int
declare @worktype int
delete from tbCustomerScheduledTemp
set @from=(select fromdate from tbCustomerScheduledRecord where id=@yearmonth)
set @end=(select enddate from tbCustomerScheduledRecord where id=@yearmonth)


--begin 順序排早中班開始,默認AB組循環上早中班,手動排班不變
set @from=(select fromdate from tbCustomerScheduledRecord where id=@yearmonth)
set @end=(select enddate from tbCustomerScheduledRecord where id=@yearmonth)

--插入手工排班班表
begin
insert into tbCustomerScheduled(customer,worktype,workday,memo,yearmonth,adddate,handinsert)
select customer,worktype,workday,memo,yearmonth,adddate,1 from tbCustomerScheduledHand sdh
where yearmonth=@yearmonth and not exists(select top 1 1 from tbCustomerScheduled sd1
where sdh.customer=sd1.customer and sd1.workday=sdh.workday and sd1.yearmonth=sdh.yearmonth)

declare @morning varchar
declare @noon varchar
set @morning=(select ISNULL((select 'A' from tbCustomerScheduledRecord where id=@yearmonth and ismorning=0),'B'))
set @noon = (select case when @morning='A' then 'B' else 'A' end)--;//B組分中班

declare @datetemp date
set @datetemp = @from;
while (@datetemp <= @end)
begin
if (select
case when datename(weekday,@datetemp)='星期日' then 0
when datename(weekday,@datetemp)='星期一' then 1
when datename(weekday,@datetemp)='星期二' then 2
when datename(weekday,@datetemp)='星期三' then 3
when datename(weekday,@datetemp)='星期四' then 4
when datename(weekday,@datetemp)='星期五' then 5
when datename(weekday,@datetemp)='星期六' then 6
else 0 end)
<
(select
case when datename(weekday,dateadd(d,-1,@datetemp))='星期日' then 0
when datename(weekday,dateadd(d,-1,@datetemp))='星期一' then 1
when datename(weekday,dateadd(d,-1,@datetemp))='星期二' then 2
when datename(weekday,dateadd(d,-1,@datetemp))='星期三' then 3
when datename(weekday,dateadd(d,-1,@datetemp))='星期四' then 4
when datename(weekday,dateadd(d,-1,@datetemp))='星期五' then 5
when datename(weekday,dateadd(d,-1,@datetemp))='星期六' then 6
else 0 end)
begin
set @morning = @noon;
if @morning='A'
set @noon='B'
else
set @noon='A'
end

select @morning

insert into tbCustomerScheduled(customer,worktype,workday,yearmonth)
select wd.customer,(select case when p.CustomerGroupBig=@morning then 1 when p.CustomerGroupBig=@noon then 2 else 1 end ),@datetemp,@yearmonth
from P_User p inner join tbCustomerScheduledWorkDay wd on p.userName=wd.customer
where wd.yearmonth=@yearmonth
and not exists(select top 1 1 from tbCustomerScheduled sd1
where wd.customer=sd1.customer and sd1.workday=@datetemp and sd1.yearmonth=@yearmonth)

set @datetemp = dateadd(d,1,@datetemp)
end
end
--end 順序排早中班結束


--排班中班早班旺旺和中民客服分開,分兩步排班
set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
--begin 排中班開始
set @worktype=2

--主站客服 begin
--算出主站客服還剩多少天中班未上
set @count=(select nooncount-(select COUNT(1) from tbCustomerScheduled d where d.worktype=@worktype and d.yearmonth=@yearmonth and d.workday=tbCustomerScheduledDutyDay.workdate and handinsert=1 and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--查詢出適合上中班的主站客服,且是主站客服
--中班的情況一般是周末,周末不讓連着上班
--當天前一天跟當天上班類型一樣或者前一天是休息才排班
--前6天不是一直上班的才排班
--前后9天沒手動排過早中班的才排班(最大化防止周末連着上班)
--假期之前安排過最多的排序上班,防止假期不夠排
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduled sd
where sd.worktype=@worktype and handinsert=0
and @date=sd.workday and sd.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,-1,sd.workday) and (sd1.worktype=@worktype or sd1.worktype=0))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd.yearmonth=@yearmonth and sd1.workday between dateadd(d,-6,@date) and @date and sd1.worktype<>0)<=6
and not exists(select top 1 1 from tbCustomerScheduled sd2
where handinsert=1 and sd2.yearmonth=@yearmonth and sd.customer=sd2.customer and sd2.worktype in(1,2)
and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
order by (select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and sd.customer=sd1.customer) desc,NEWID()
set @count = @count-@@rowcount
--如果上面條件沒找到客服或者客服不夠上中班
--排查9天上班限制(周末連着上班)
if @count>0
begin
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduled sd
where sd.worktype=@worktype and handinsert=0
and @date=sd.workday and sd.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,-1,sd.workday) and (sd1.worktype=@worktype or sd1.worktype=0))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-6,@date) and @date and sd1.worktype<>0)<=6
--and not exists(select top 1 1 from tbCustomerScheduled sd2
--where handinsert=1 and sd.customer=sd2.customer and sd2.worktype in(1,2)
--and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
order by (select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and sd.customer=sd1.customer) desc,NEWID()
end

update tbCustomerScheduled set worktype=@worktype,handinsert=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduled set worktype=0
where workday=@date and handinsert=0 and worktype=@worktype and yearmonth=@yearmonth
and customer not in(select customer from tbCustomerScheduledTemp)
end
--主站客服 end

--end 排中班結束

--begin 排早班開始
set @worktype=1
--主站客服begin
set @count=(select morningcount-(select COUNT(1) from tbCustomerScheduled d where d.worktype=@worktype and d.workday=dd.workdate and handinsert=1 and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay dd where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--跟中班規則一樣
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduled sd
where sd.worktype=@worktype and handinsert=0
and @date=sd.workday and sd.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer
and sd1.yearmonth=@yearmonth and sd1.workday=dateadd(d,-1,sd.workday) and (sd1.worktype=@worktype or sd1.worktype=0))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-6,@date) and @date and sd1.worktype<>0)<=6
and not exists(select top 1 1 from tbCustomerScheduled sd2
where handinsert=1 and sd2.yearmonth=@yearmonth and sd.customer=sd2.customer and sd2.worktype in(1,2,3)
and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
order by (select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and sd1.yearmonth=@yearmonth and sd.customer=sd1.customer) desc,NEWID()
set @count = @count-@@rowcount
--跟中班規則一樣
if @count>0
begin
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduled sd
where sd.worktype=@worktype and handinsert=0
and @date=sd.workday and sd.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,-1,sd.workday) and (sd1.worktype=@worktype or sd1.worktype=0))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-6,@date) and @date and sd1.worktype<>0)<=6
--and not exists(select top 1 1 from tbCustomerScheduled sd2
--where handinsert=1 and sd.customer=sd2.customer and sd2.worktype in(1,2,3)
--and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=sd.customer)
order by (select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and sd.customer=sd1.customer) desc,NEWID()
end

update tbCustomerScheduled set worktype=@worktype,handinsert=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduled set worktype=0
where workday=@date and handinsert=0 and worktype=@worktype and yearmonth=@yearmonth
and customer not in(select customer from tbCustomerScheduledTemp)

end
--主站客服 end

--早班結束

set @i=@i+1
end


--設置每個客服該上晚班的天數
update tbCustomerScheduledWorkDay set nightdaytemp=nightday-(select COUNT(1) from tbCustomerScheduled d where d.worktype=3 and d.yearmonth=@yearmonth and d.customer=tbCustomerScheduledWorkDay.customer and yearmonth=@yearmonth) where yearmonth=@yearmonth

--begin 排晚班開始
set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
set @worktype=3
set @count=(select nightcount-(select COUNT(1) from tbCustomerScheduled d where d.worktype=@worktype and d.yearmonth=@yearmonth and d.workday=tbCustomerScheduledDutyDay.workdate and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--晚班優先排在6天班之內,且6天班前后不排晚班(最大的減少6天班的存在)
--在非手工排班內,安排系統排班的早中班選擇晚班
--晚班后一天且不為手工排班
--9天內上過晚班的不排晚班
--晚班還剩最多的排序,假期最少的排序
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where
wk.nightdaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2)
and handinsert=0 and sd.customer=wk.customer and @date=sd.workday and sd.yearmonth=@yearmonth
and not exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,1,sd.workday) and sd1.handinsert=1))
and (((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between @date and dateadd(d,1,@date)
and sd1.worktype<>0)=2
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between dateadd(d,-4,@date) and @date
and sd1.worktype<>0)=5)
or ((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between @date and dateadd(d,2,@date)
and sd1.worktype<>0)=3
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between dateadd(d,-3,@date) and @date
and sd1.worktype<>0)=4)
or ((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between @date and dateadd(d,3,@date)
and sd1.worktype<>0)=4
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between dateadd(d,-2,@date) and @date
and sd1.worktype<>0)=3)
or ((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between @date and dateadd(d,4,@date)
and sd1.worktype<>0)=5
and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth
and sd1.workday between dateadd(d,-1,@date) and @date
and sd1.worktype<>0)=2)
)

and not exists(select top 1 1 from tbCustomerScheduled sd2 where sd2.customer=wk.customer and sd2.yearmonth=@yearmonth
and sd2.worktype=3 and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=wk.customer)
order by nightdaytemp desc,(select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and wk.customer=sd1.customer) asc,NEWID()

set @count = @count-@@rowcount
--如果當天的還沒有安排完,則往下走
--在非手工排班內,安排系統排班的早中班選擇晚班
--晚班后一天且不為手工排班
--
if @count>0
begin
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where wk.nightdaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and handinsert=0 and sd.customer=wk.customer and @date=sd.workday and sd.yearmonth=@yearmonth
and not exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd.workday=dateadd(d,-1,sd1.workday) and sd1.handinsert=1))
and not exists(select top 1 1 from tbCustomerScheduled sd2 where sd2.customer=wk.customer and sd2.yearmonth=@yearmonth
and sd2.worktype=3 and sd2.workday between dateadd(d,-9,@date) and dateadd(d,9,@date))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=wk.customer)
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.workday=DATEADD(d,1,@date) and sd1.yearmonth=@yearmonth and sd1.worktype=0 and sd1.handinsert<>1)
--and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.workday=dateadd(d,-5,@date) and sd1.worktype=0)
--and (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.workday between dateadd(d,-4,@date) and @date and sd1.worktype<>0)=5
order by nightdaytemp desc,(select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and wk.customer=sd1.customer) asc,NEWID()
set @count = @count-@@rowcount
if @count>0--如果當天的還沒有安排完,則隨機安排還剩夜班最多的客服
--if 1=2
begin
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk
where wk.nightdaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd
where sd.worktype in (0,1,2) and handinsert=0 and sd.yearmonth=@yearmonth
and sd.customer=wk.customer and @date=sd.workday
and not exists(select top 1 1 from tbCustomerScheduled sd1
where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd.workday=dateadd(d,-1,sd1.workday) and sd1.handinsert=1 and sd1.worktype not in(0,3)))
and not exists(select top 1 1 from tbCustomerScheduled sd2
where sd2.customer=wk.customer and sd2.yearmonth=@yearmonth
and sd2.worktype=3 and sd2.workday
between dateadd(d,-9,@date) and dateadd(d,9,@date))
and not exists(select top 1 1 from tbCustomerScheduledTemp tp1 where tp1.customer=wk.customer)
order by (select COUNT(1) from tbCustomerScheduled sd1 where sd1.worktype=0 and sd1.yearmonth=@yearmonth and wk.customer=sd1.customer) asc,nightdaytemp desc,NEWID()

end
end

update tbCustomerScheduled set worktype=@worktype,handinsert=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set nightdaytemp=nightdaytemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
set @i=@i+1
end
--end 排晚班結束

 

--begin 晚班之后接着休息日
update sd set worktype=0 from (select customer,dateadd(d,1,workday) workday from tbCustomerScheduled sd where worktype=3 and yearmonth=@yearmonth and dateadd(d,1,workday) between (select fromdate from tbCustomerScheduledRecord where id=@yearmonth) and (select enddate from tbCustomerScheduledRecord where id=@yearmonth))sd1 inner join tbCustomerScheduled sd on sd1.customer=sd.customer and sd1.workday=sd.workday and sd.yearmonth=@yearmonth and sd.handinsert=0
--然后計算客服還剩多少假日
update tbCustomerScheduledWorkDay set leavedaytemp=leaveday-(select COUNT(1) from tbCustomerScheduled d where d.worktype=0 and d.yearmonth=@yearmonth and d.customer=tbCustomerScheduledWorkDay.customer and d.yearmonth=@yearmonth) where yearmonth=@yearmonth


--這里處理旺旺客服的休息天數
declare @leavecustomer int
declare @sexworkcount int
--循環查找上班6天的客服,3次應該夠了,如果有6天班的情況這里就要多循環幾次
--或者去安排6天班的第二天休息,這里只安排第三、第四天休息
set @sexworkcount=3
while @sexworkcount>0 and exists(select top 1 1 from tbCustomerScheduled sd
where (select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-5,sd.workday) and sd.workday and sd1.worktype<>0)>5 and sd.yearmonth=@yearmonth)
begin
--排假日日期全部沒安排休假的客服全部安排休假
set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
set @worktype=0
--主站客服 begin
delete tbCustomerScheduledTemp
--1,2小組同一天休息人數不可大於大組人數的1/@maxleave,周末除外。3,4小組同樣要求。
--查詢出今天能安排的休息人數,對於周末已經安排了
--主站客服休息人數
set @leavecustomer=(select COUNT(1) from tbCustomerScheduled sd where worktype=0 and sd.workday=@date and sd.yearmonth=@yearmonth )--休息人數

--主站客服,最大可休息人數
set @count=(select COUNT(1) from tbCustomerScheduledWorkDay where yearmonth=@yearmonth)/@maxleave-@leavecustomer
--有沒排班主站客服的且最大休息人數大於0就去尋找最優休息客服
if @count>0 and (select COUNT(1) from tbCustomerScheduled sd where handinsert=0 and sd.yearmonth=@yearmonth )>0
begin
--前后有連續上班6天的,如果當天不是手動排班,設置休息日。如果客服有休息日的時候
insert into tbCustomerScheduledTemp(customer)
select * from (select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
and(((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-2,@date) and @date and sd1.worktype<>0)=3
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,3,@date) and sd1.worktype<>0)=4)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-3,@date) and @date and sd1.worktype<>0)=4
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,2,@date) and sd1.worktype<>0)=3)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-1,@date) and @date and sd1.worktype<>0)=2
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,4,@date) and sd1.worktype<>0)=5)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-4,@date) and @date and sd1.worktype<>0)=5
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,1,@date) and sd1.worktype<>0)=2)
)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='A')
union
select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
and(((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-2,@date) and @date and sd1.worktype<>0)=3
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,3,@date) and sd1.worktype<>0)=4)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-3,@date) and @date and sd1.worktype<>0)=4
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,2,@date) and sd1.worktype<>0)=3)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-1,@date) and @date and sd1.worktype<>0)=2
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,4,@date) and sd1.worktype<>0)=5)
or((select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between dateadd(d,-4,@date) and @date and sd1.worktype<>0)=5
and(select COUNT(1) from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and sd1.workday between @date and dateadd(d,1,@date) and sd1.worktype<>0)=2)
)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='B'))a
order by NEWID()

delete tbCustomerScheduledTemp where
customer not in(select top (@count) customer from tbCustomerScheduledTemp order by NEWID())

update tbCustomerScheduled set worktype=@worktype
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set leavedaytemp=leavedaytemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
--主站客服end


set @i=@i+1
end

set @sexworkcount=@sexworkcount-1
end
--end 排假日結束


--排假日日期全部沒安排休假的客服全部安排休假
set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
set @worktype=0
--主站客服 begin
delete tbCustomerScheduledTemp
--1,2小組同一天休息人數不可大於大組人數的1/@maxleave,周末除外。3,4小組同樣要求。
--查詢出今天能安排的休息人數,對於周末已經安排了
--declare @workcustomer int
set @leavecustomer=(select COUNT(1) from tbCustomerScheduled sd where worktype=0 and sd.workday=@date and sd.yearmonth=@yearmonth )--休息人數

--最大可休息人數
set @count=(select COUNT(1) from tbCustomerScheduledWorkDay where yearmonth=@yearmonth )/@maxleave-@leavecustomer
--有沒排班的且最大休息人數大於0就去尋找最優休息客服
if @count>0 and (select COUNT(1) from tbCustomerScheduled where handinsert=0 and yearmonth=@yearmonth )>0
begin
--這里優先安排休息日之后再休息
insert into tbCustomerScheduledTemp(customer)
select * from (select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and (sd1.workday =DATEADD(d,-1, @date) or sd1.workday =DATEADD(d,1, @date)) and sd1.worktype=0)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='A')
union
select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and (sd1.workday =DATEADD(d,-1, @date) or sd1.workday =DATEADD(d,1, @date)) and sd1.worktype=0)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='B'))a
order by NEWID()

delete tbCustomerScheduledTemp where
customer not in(select top (@count) customer from tbCustomerScheduledTemp order by NEWID())

update tbCustomerScheduled set worktype=@worktype
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set leavedaytemp=leavedaytemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
--主站客服 end

set @i=@i+1
end
--end 排假日結束

 

--排假日日期全部沒安排休假的客服全部安排休假--防止還有人沒安排休假的情況,隨機安排
set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
set @worktype=0
--主站客服 begin
delete tbCustomerScheduledTemp
--1,2小組同一天休息人數不可大於大組人數的1/@maxleave,周末除外。3,4小組同樣要求。
--查詢出今天能安排的休息人數,對於周末已經安排了
--declare @workcustomer int
set @leavecustomer=(select COUNT(1) from tbCustomerScheduled sd where worktype=0 and sd.workday=@date and sd.yearmonth=@yearmonth )--休息人數

--最大可休息人數
set @count=(select COUNT(1) from tbCustomerScheduledWorkDay where yearmonth=@yearmonth )/@maxleave-@leavecustomer
--有沒排班的且最大休息人數大於0就去尋找最優休息客服
if @count>0 and (select COUNT(1) from tbCustomerScheduled where handinsert=0 and yearmonth=@yearmonth )>0
begin
--這里優先安排休息日之后再休息
insert into tbCustomerScheduledTemp(customer)
select * from (select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=wk.customer and sd1.yearmonth=@yearmonth and (sd1.workday =DATEADD(d,-1, @date) or sd1.workday =DATEADD(d,1, @date)) and sd1.worktype=0)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='A')
union
select top (cast((round(@count/2.0,0)) as int)) customer
from tbCustomerScheduledWorkDay wk where leavedaytemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype in (1,2) and sd.yearmonth=@yearmonth and handinsert=0 and wk.customer=sd.customer and sd.workday=@date)
--and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=wk.customer and (sd1.workday =DATEADD(d,-1, @date) or sd1.workday =DATEADD(d,1, @date)) and sd1.worktype=0)
and exists(select top 1 1 from P_User u1 where u1.userName=wk.customer and u1.CustomerGroupBig='B'))a
order by NEWID()

delete tbCustomerScheduledTemp where
customer not in(select top (@count) customer from tbCustomerScheduledTemp order by NEWID())

update tbCustomerScheduled set worktype=@worktype
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set leavedaytemp=leavedaytemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
--主站客服 end

set @i=@i+1
end
--end 排假日結束

--中長班
begin
--設置每個客服該上中長班的天數,使用longnoontemp做臨時變量使用
update tbCustomerScheduledWorkDay set longnoontemp=longnoon-(select COUNT(1) from tbCustomerScheduled d where d.longnoon<>0 and d.customer=tbCustomerScheduledWorkDay.customer and yearmonth=@yearmonth) where yearmonth=@yearmonth

set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)
set @count=(select longnooncount-(select COUNT(1) from tbCustomerScheduled d where d.longnoon<>0 and d.workday=tbCustomerScheduledDutyDay.workdate and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--選擇當天是中班的客服
--優先排班后一天是休息的客服
--中長班還剩最多的排序
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where
wk.longnoontemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype=2
and sd.customer=wk.customer and @date=sd.workday and sd.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd1 where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,1,sd.workday) and sd1.worktype in(0,3)))

order by longnoontemp desc,NEWID()

set @count = @count-@@rowcount
--如果當天的還沒有安排完,則往下走
--在非手工排班內選擇當天是中班的客服
--次之,排班,后一天是中中班的客服
--中長班還剩最多的排序
if @count>0
begin
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where
wk.longnoontemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype=2
and sd.customer=wk.customer and @date=sd.workday and sd.yearmonth=@yearmonth
and not exists(select top 1 1 from tbCustomerScheduled sd1
where sd1.customer=sd.customer and sd1.yearmonth=@yearmonth
and sd1.workday=dateadd(d,1,sd.workday) and sd1.worktype in(0,1,3)))

order by longnoontemp desc,NEWID()
end

update tbCustomerScheduled set longnoon=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set longnoontemp=longnoontemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
set @i=@i+1
end

end
--中長班


/*
--紅人 早班紅人,中班紅人
begin
--設置每個客服該上紅人的天數,使用isredtemp做臨時變量使用
update tbCustomerScheduledWorkDay set isredtemp=isred-(select COUNT(1) from tbCustomerScheduled d where d.isred<>0 and d.customer=tbCustomerScheduledWorkDay.customer and yearmonth=@yearmonth) where yearmonth=@yearmonth

set @i=0
while @i<=DATEDIFF(d,@from,@end)
begin
set @date=DATEADD(d,@i,@from)

--早班紅人開始
begin
set @count=(select isredcount-(select COUNT(1) from tbCustomerScheduled d where d.isred<>0 and d.workday=tbCustomerScheduledDutyDay.workdate and d.worktype=1 and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--選擇當天是早班的客服
--紅人還剩最多的排序
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where
wk.isredtemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype=1
and sd.customer=wk.customer and @date=sd.workday)

order by isredtemp desc,NEWID()

update tbCustomerScheduled set isred=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set isredtemp=isredtemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
end --早班結束


--中班紅人開始
begin
set @count=(select isrednooncount-(select COUNT(1) from tbCustomerScheduled d where d.isred<>0 and d.workday=tbCustomerScheduledDutyDay.workdate and d.worktype=2 and yearmonth=@yearmonth) from tbCustomerScheduledDutyDay where workdate=@date and yearmonth=@yearmonth)
delete tbCustomerScheduledTemp
if @count>0
begin
--選擇當天是中班的客服
--紅人還剩最多的排序
insert into tbCustomerScheduledTemp(customer)
select top (@count) customer
from tbCustomerScheduledWorkDay wk where
wk.isredtemp>0 and wk.yearmonth=@yearmonth
and exists(select top 1 1 from tbCustomerScheduled sd where sd.worktype=2
and sd.customer=wk.customer and @date=sd.workday)

order by isredtemp desc,NEWID()

update tbCustomerScheduled set isred=1
where workday=@date and yearmonth=@yearmonth
and customer in(select customer from tbCustomerScheduledTemp)

update tbCustomerScheduledWorkDay set isredtemp=isredtemp-1
where customer in(select customer from tbCustomerScheduledTemp)
and yearmonth=@yearmonth
end
end --中班紅人結束


set @i=@i+1
end

end
--紅人 */


GO

 

 


支持原創:如有問題或者不同見解請聯系 cheerfulhuang@yeah.net

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM