我有一个包含以下值的表;
Earnings Penalties
1000 500
0 500
0 100
0 100
500 100
400 500
每当cumulative
总和(收入-罚金)值大于或等于0时,将仅应用罚款。否则应为零。
我不需要使用Cursor
或While
循环的任何查询。我需要高性能的查询。
我想要下面的结果,
AttDay Earnings Penalties IsPenaltyApplicable Reason
2019-05-01 1000 500 Yes (1000-500=500) Remaining 500
2019-05-02 0 500 Yes (500-500=0) Remaining 0
2019-05-03 0 100 Yes (0-100=-100) Remaining -100
2019-05-04 0 100 No 0
2019-05-05 500 100 Yes (500-100=400) Remaining 400
2019-05-06 400 500 Yes (400-500=-100) Remaining -100
答案 0 :(得分:1)
CASE .. WHEN ..将适用于同一情况。
CREATE TABLE #penaltytest
(
Earnings NUMERIC(7,2),
Penalties NUMERIC(7,2)
)
INSERT INTO #penaltytest VALUES (1000,500)
INSERT INTO #penaltytest VALUES (0,500)
INSERT INTO #penaltytest VALUES (0,100)
INSERT INTO #penaltytest VALUES (0,100)
INSERT INTO #penaltytest VALUES (500,100)
INSERT INTO #penaltytest VALUES (400,500)
SELECT *,CASE WHEN (Earnings-Penalties) >0 THEN 'Yes' ELSE 'No' END AS 'IsPenaltyApplicable',CASE WHEN (Earnings-Penalties) >0 THEN (Earnings-Penalties) ELSE 0 END AS PenaltyAmount FROM #penaltytest
答案 1 :(得分:1)
CREATE TABLE #penaltytest
(
Earnings NUMERIC(7,2),
Penalties NUMERIC(7,2),
AttDate DATE
)
INSERT INTO #penaltytest VALUES (1000,500, '01 Jan 2000')
INSERT INTO #penaltytest VALUES (0,500, '02 Jan 2000')
INSERT INTO #penaltytest VALUES (0,100, '03 Jan 2000')
INSERT INTO #penaltytest VALUES (0,100, '04 Jan 2000')
INSERT INTO #penaltytest VALUES (500,100, '05 Jan 2000')
INSERT INTO #penaltytest VALUES (400,500, '06 Jan 2000')
;with cte as(
select
AttDate,
Earnings,
Penalties,
Earnings - Penalties as subTotal,
(select
isnull(sum(Earnings - Penalties),0)
from
#penaltytest previousRow
where
previousRow.AttDate < currentRow.AttDate
) as cumulative
from
#penaltytest currentRow
)
select
t.AttDate
,t.Earnings
,t.Penalties
,cte.subTotal
,cte.cumulative
,case when cte.cumulative - (t.Earnings - t.Penalties) >= 0 then 'Yes' else 'No' end as Penalty
from #penaltytest t
join cte
on cte.AttDate = t.AttDate
drop table #penaltytest
Results:
AttDate Earnings Penalties subTotal cumulative Penalty
2000-01-01 1000.00 500.00 500.00 0.00 No
2000-01-02 0.00 500.00 -500.00 500.00 Yes
2000-01-03 0.00 100.00 -100.00 0.00 Yes
2000-01-04 0.00 100.00 -100.00 -100.00 Yes
2000-01-05 500.00 100.00 400.00 -200.00 No
2000-01-06 400.00 500.00 -100.00 200.00 Yes
答案 2 :(得分:0)
我将使用累积方法:
select pt.*,
sum(case when IsPenaltyApplicable = 1 then Earnings - Penalties else 0 end) over (partition by grp order by AttDay)
from (select t.*, sum(case when IsPenaltyApplicable = 0 then 1 else 0 end) over (order by AttDay) as grp
from table t
) pt;