Reputation: 75
I have data like this :
Ranking | Quota | Amount
---------------------------
9503 | 2000 | 0
9408 | 1800 | 1800
9407 | 1800 | 1800
9406 | 1800 | 0
9405 | 1500 | 0
9404 | 1100 | 2000
1403 | 1000 | 0
I also have a variable contains previous amount from another query, lets say this variable name is @Previous_Amount and the value is 500. I have to calculate SUM(Amount) - @Previous_Amount then do the running difference but have to check the column Quota.
In this example, SUM(Amount) - @Previous_Amount = 5600 - 500 = 5100, so my expected result is like this :
Ranking | Quota | Amount | Cum_Diff
------------------------------------
9503 | 2000 | 0 | 2000
9408 | 1800 | 1800 | 1800
9407 | 1800 | 1800 | 1300
9406 | 1800 | 0 | 0
9405 | 1500 | 0 | 0
9404 | 1100 | 2000 | 0
1403 | 1000 | 0 | 0
I have to split 5100 based on quota.
Note : the ranking column is a generated column based on certain condition, so the cum_diff will fill order by ranking desc
Anyone have idea how to do this ?
Upvotes: 0
Views: 91
Reputation: 886
You can use the ROWS BETWEEN
FOR BOTH SUM(Amount)
AND SUM(QUOTA)
and then a CASE expression. I've used a CTE for a more modular approach
DECLARE @Previous_Amount INT =500
;WITH CTE AS
(
SELECT SUM(AMOUNT) OVER (ORDER BY Ranking DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
- @Previous_Amount - ISNULL(SUM(QUOTA) OVER (ORDER BY Ranking DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ),0) AS ComputedDifferenc, *
FROM @TABLE1
)
SELECT Ranking,Quota,Amount,CASE WHEN ComputedDifferenc > Quota THEN Quota ELSE CASE WHEN ComputedDifferenc >0 THEN ComputedDifferenc ELSE 0 END END AS Cum_Diff
FROM CTE
Upvotes: 1
Reputation: 95830
You can use ROWS BETWEEN
to get a cumulative SUM
, and then we can use a CASE
to display the appropriate values:
CREATE TABLE dbo.TestTable (Ranking int,
Quota int,
Amount int);
INSERT INTO dbo.TestTable (Ranking,
Quota,
Amount)
VALUES(9503,2000,0),
(9408,1800,1800),
(9407,1800,1800),
(9406,1800,0),
(9405,1500,0),
(9404,1100,2000),
(1403,1000,0);
GO
DECLARE @Previous_Amount int = 5100;
WITH CTE AS(
SELECT TT.Ranking,
TT.Quota,
TT.Amount,
@Previous_Amount - SUM(TT.Quota) OVER (ORDER BY TT.Ranking DESc
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Cumulative
FROM dbo.TestTable TT)
SELECT C.Ranking,
C.Quota,
C.Amount,
CASE WHEN C.Cumulative > 0 THEN C.Quota
WHEN C.Quota + C.Cumulative > 0 THEN C.Quota + C.Cumulative
ELSE 0
END AS Cum_Diff
FROM CTE C
ORDER BY C.Ranking DESC;
GO
DROP TABLE dbo.TestTable;
(Assumes you are using a supported version of SQL Server, but I'll suggest that's a safe assumption as you haven't mentioned you are using an unsupported version.)
Upvotes: 1