Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sql dynamic cumulative sum - SQL Server

I have a table like this

+------+--------+
|   ID | Salary | 
+------+--------+
| 1    |    100 |
| 2    |     40 |
| 3    |     30 |
| 4    |     40 |
| 5    |     90 |
| 6    |    160 |
| 7    |     70 |
| 8    |     40 |
| 9    |     20 |
| 10   |     10 |
| 11   |    200 | 
| 12   |     50 |
+------+--------+

I can make normal cumulative sum but i need something different from normal CUMULATIVE SUM. If the cumulative sum is %50 higher than the last sum, for the next cumulative sums start from this value

+------+--------+---------------+
|   ID | Salary | Running Total |
+------+--------+---------------+
| 1    |    100 |           100 |
| 2    |     40 |           140 |
| 3    |     30 |           170 |
| 4    |     40 |           210 |
| 5    |     90 |           300 |
| 6    |    160 |           460 |
| 7    |     70 |           230 |
| 8    |     40 |           270 |
| 9    |     20 |           290 |
| 10   |     10 |           300 |
| 11   |    200 |           500 |
| 12   |     50 |           250 |
+------+--------+---------------+

I want a output like this.

like image 699
Gork. O Avatar asked Mar 07 '23 01:03

Gork. O


1 Answers

Answer for Your Second Question:

DECLARE @MIN INT, @MAX INT, @PreVal INT, @CurVal INT, @OldVal INT,@NextVal INT, @ExistVal INT
DECLARE @TABLE1 TABLE(ID INT, Sal INT, RunTotal INT,TimesGen INT)

INSERT INTO @TABLE1 (Id, Sal)
SELECT * FROM @TAB

SELECT @MIN=MIN(ID),@MAX=MAX(ID) FROM @TAB

WHILE(@MIN<=@MAX)
BEGIN
    SELECT @NextVal=SALARY FROM @TAB WHERE ID=@MIN
    SELECT @ExistVal=SALARY FROM @TAB WHERE ID=@MIN-1
    SELECT @OldVal=RunTotal FROM @TABLE1 WHERE ID=@MIN-1
    SELECT @PreVal=RunTotal FROM @TABLE1 WHERE ID=@MIN-2

    IF(@OldVal>@PreVal+(@PreVal/2))
    BEGIN
        SELECT @CurVal = @NextVal--+@ExistVal
        UPDATE @TABLE1 SET TimesGen=1 WHERE ID=@MIN 
    END
    ELSE
    BEGIN
        SELECT @CurVal=ISNULL(@OldVal,0)+@NextVal-- FROM @TABLE1 WHERE ID=@MIN
        UPDATE @TABLE1 SET TimesGen=ISNULL((SELECT TimesGen FROM @TABLE1 WHERE ID=@MIN-1),0)+1 WHERE ID=@MIN
    END

    UPDATE @TABLE1 SET RunTotal=@CurVal WHERE ID=@MIN
    SELECT @MIN=@MIN+1
END

SELECT ID,Sal Salary
    ,'('+CAST(RunTotal AS VARCHAR)+'/'+CAST(TimesGen AS VARCHAR)+') '+CAST(CAST(RunTotal*1.0/TimesGen AS NUMERIC(8,1)) AS VARCHAR) MovingAvg
    ,CAST(RunTotal*1.0/TimesGen AS NUMERIC(8,1))MovingAvg1
FROM @TABLE1

OutPut:

ID  Salary  MovingAvg
1   100     (100/1) 100.0
2   40      (140/2) 70.0
3   30      (170/3) 56.7
4   40      (210/4) 52.5
5   90      (300/5) 60.0
6   160     (460/6) 76.7
7   70      (230/2) 115.0
8   40      (270/3) 90.0
9   20      (290/4) 72.5
10  10      (300/5) 60.0
11  200     (500/6) 83.3
12  50      (250/2) 125.0
like image 59
DineshDB Avatar answered Mar 19 '23 09:03

DineshDB