Home > OS >  How to sum up and other calculations by the other columns in the same table?
How to sum up and other calculations by the other columns in the same table?

Time:11-18

SELECT * FROM INVOICE;
id amount
1 20
2 20
3 20
4 30
5 100
6 20
7 30
8 100

I would like to create three more columns which will be calculated by the amount column.

openamt  = Sum of amount
debamt   = Sum of amount where amount < 50
credamt  = Sum of amount where amount > 50
closeamt = openamt - debamt   credamt

Expected output:

id amount openamt debamt credamt closeamt
1 20 340 140 200 400
2 20 340 140 200 400
3 20 340 140 200 400
4 30 340 140 200 400
5 100 340 140 200 400
6 20 340 140 200 400
7 30 340 140 200 400
8 100 340 140 200 400

What I tried, I got it working for openamt but not for the rest. Can somebody point out me to the right direction, please?

SELECT 
    ID, 
    AMOUNT, 
    SUM(AMOUNT) OVER () AS OPENAMT,
    (SELECT SUM(AMOUNT) FROM INVOICE WHERE AMOUNT < 0) AS DEBTAMT,  -- This is how I want
    (SELECT SUM(AMOUNT) FROM INVOICE WHERE AMOUNT > 0) AS CREDAMT,   -- This is how i want
    (OPENAMT - DEBTAMT   CREDAMT) AS CLOSEAMT
FROM 
    INVOICE

CodePudding user response:

You were in the right area. You can use a conditional aggregation within the window function sum() over()

Example

Declare @YourTable Table ([id] int,[amount] int)  Insert Into @YourTable Values 
 (1,20)
,(2,20)
,(3,20)
,(4,30)
,(5,100)
,(6,20)
,(7,30)
,(8,100)
 
Select * 
      ,openamt  = sum(amount) over()
      ,debamt   = sum( case when amount<50 then amount end) over()
      ,credamt  = sum( case when amount>=50 then amount end) over()
      ,closeamt = sum(amount) over()
                 -sum( case when amount<50 then amount end) over()
                  sum( case when amount>=50 then amount end) over()
 From @YourTable

Results

enter image description here

CodePudding user response:

If the definition of credamt includes the = sign also like this:

credamt = Sum of amount where amount >= 50

then closeamt is just twice closeamt because obviously:

openamt = debamt   credamt

so:

closeamt = openamt - debamt   credamt
         = (debamt   credamt) - debamt   credamt
         = 2 * credamt

Use SUM() window function:

SELECT *, 
       SUM(amount) OVER() openamt,
       SUM(CASE WHEN amount < 50 THEN AMOUNT ELSE 0 END) OVER() debamt,
       SUM(CASE WHEN amount >= 50 THEN AMOUNT ELSE 0 END) OVER() credamt,
       2 * SUM(CASE WHEN amount >= 50 THEN AMOUNT ELSE 0 END) OVER() closeamt
FROM tablename;

See the demo.

  • Related