SQL資料分攤

2021-08-20 21:52:11 字數 3085 閱讀 1557

/*----------------------------------------

場景:到季未公司按照部門貢獻率進行對各部門發放獎金,然後部門內部按效績優先順序分攤獎金

方案:參考網上資料,使用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 校驗和 集群中的...