/*----------------------------------------
場景:到季未公司按照部門貢獻率進行對各部門發放獎金,然後部門內部按效績優先順序分攤獎金
方案:參考網上資料,使用cte函式遞迴處理
----------------------------------------
*/if object_id('tempdb..#emplbonus') is not null drop table #emplbonus
create table #emplbonus(pn
int,--優先序號
deptno
int,--部門
empno
int,--員工
bonus
int--獎金
)insert into #emplbonus
values(1,1001,5001,900)
,(2,1001,5002,1000)
,(3,1001,5003,900)
,(4,1002,5004,1500)
,(5,1002,5005,1200)
,(6,1002,5006,1600)
,(7,1003,5007,500)
drop table #tmpbonus
create table #tmpbonus
(dept
int,--部門
bonus
int--獎金
)insert into #tmpbonus
values(1001,2000),(1002,6000),(1003,200)
with tmpa as(
select dense_rank() over( order by deptno) as deptnum,row_number() over(partition by deptno order by deptno,pn) as deptln,*
,(select cast(e.bonus as numeric(24,12))/(case when sum(tmpb.bonus)=0 then 1 else sum(tmpb.bonus) end) from #emplbonus tmpb where tmpb.deptno=e.deptno) rate
from #emplbonus e
)--部門員工內部序號
,tmpb as(
select (select max(deptln) from tmpa m where m.deptnum=tmpa.deptnum) maxdeptln,* from tmpa
)--部門內部最大序號
,tmpc (maxdeptln,deptnum,deptln,pn,deptno,empno,bonus,curleft,total,preleft,allocate,noallocate) as
(select maxdeptln,deptnum,deptln,pn,deptno,empno,bonus
,isnull((select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno)-bonus,0) curleft --當前剩餘分攤數
,bonus total
,isnull((select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno),0) preleft --前乙個剩餘分攤數
,isnull(
(case when ((select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno)-bonus)<0--業績獎金大於分攤數則取分攤數
then (select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno)
when maxdeptln=deptln and (select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno)>bonus--最後乙個員工業績獎金小於分攤數則取分攤數
then (select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno)
else bonus end) ,0) allocate --其他情況取業績獎金,無部門獎金則為0
,case when (select top 1 b.bonus from #tmpbonus b where b.dept=tmpb.deptno) is null then 1 else 0 end noallocate --是否有部門獎金分攤
from tmpb
where 1=1 and tmpb.deptln=1 ----取各部門第1個優先員工開始分攤
union all
select b.maxdeptln,b.deptnum,b.deptln,b.pn,b.deptno,b.empno,b.bonus,a.curleft-b.bonus,a.total+b.bonus,a.curleft preleft
,(case when (a.curleft-b.bonus)<0 then a.curleft when b.maxdeptln=b.deptln and a.curleft>b.bonus then a.curleft else b.bonus end) allocate,a.noallocate
from tmpc a,tmpb b
where 1=1
and a.deptln=b.deptln-1 -----遞迴對部門下乙個員工分攤
and a.deptno=b.deptno
and a.curleft>0 --------剩餘分攤大於0
)select a.pn,a.deptno,a.empno,a.bonus,a.curleft,a.total,a.preleft
,case when a.noallocate=1 then 0 else a.allocate end allocate--無部門獎金的重置分攤數為0
from(
select * from tmpc
where 1=1
) aorder by a.deptno,a.deptln
分攤分析介紹
分攤分析 1 給我的印象是大概是心理安慰,讓我們放心的用,而不去擔心會有什麼壞的效能問題。比如c 的vector 動態增長,每個操作的分攤時間複雜度是o 3 有三種操作手法 聚類方法 最壞情形下,一系列操作總的代價上界除以操作個數,就是每個操作的分攤代價。這裡每個操作的分攤代價相同。例子 二進位制計...
分攤 分配 定期重過賬
分攤是既分攤初級成本又分攤次級成本至co中物件的方法。成本分攤的規則可以有很多,比如根據統計指標,根據百分比,根據權重,根據固定金額等等。我們在系統中將分攤規則定義在乙個重要的引數 分攤迴圈中。分攤迴圈是多行的。每一行中都定義了分攤成本流的傳送方,接受方,分攤規則等內容。在月末我們指定需要執行的迴圈...
併發寫操作, redis如何分攤?
什麼是slots 乙個 redis 集群包含 16384 個插槽 hash slot 資料庫中的每個鍵都屬於這 16384 個插槽的其中乙個,集群使用公式 crc16 key 16384 來計算鍵 key 屬於哪個槽,其中 crc16 key 語句用於計算鍵 key 的 crc16 校驗和 集群中的...