Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accumulating previous rows with grouping

I have this table on MS SQL Server

Customer    Month    Amount
-----------------------------
Tom         1        10
Kate        1        60
Ali         1        70
Tom         2        50
Kate        2        40
Tom         3        80
Ali         3        20

I want the select to get accumulation of the customer for each month

Customer    Month    Amount
-----------------------------
Tom         1        10
Kate        1        60
Ali         1        70
Tom         2        60
Kate        2        100
Ali         2        70
Tom         3        140
Kate        3        100
Ali         3        90

Noticing that Ali has no data for the month of 2 and Kate has no data for the month of 3

I have done it but the problem is that for the missing month for each customer no data shows i.e. Kate has to be in month 3 with 100 amount and Ali has to be in Month 2 with 70 amount

declare @myTable as TABLE   (Customer varchar(50), Month int, Amount int)
;

INSERT INTO @myTable
    (Customer, Month, Amount)
VALUES
    ('Tom', 1, 10),
    ('Kate', 1, 60),
    ('Ali', 1, 70),
    ('Tom', 2, 50),
    ('Kate', 2, 40),
    ('Tom', 3, 80),
    ('Ali', 3, 20);


select * from @myTable


select
    SUM(b.Amount),a.Customer, a.Month
from
    @myTable a
        inner join
    @myTable b
        on a.Customer = b.Customer and 
            a.Month >= b.Month
group by
    a.Customer, a.Month
like image 469
asmgx Avatar asked Mar 22 '18 03:03

asmgx


2 Answers

Use window function

select Customer, Month,
       sum(Amount) over (partition by customer order by month) Amount
from table t

So, you want some kind of look up tables which has possible months with customers.

with cte as
(
     select * from (
        select Customer from table 
        group by Customer)c 
     cross join (values (1),(2),(3))a(Months) 
) -- look-up table 

select c.Customer, c.Months, 
       sum(t.Amount) over (partition by c.Customer order by c.Months) Amount 
from cte c left join table t 
      on t.Month = c.Months and t.Customer  = c.Customer

Result :

Customer Months Amount
Tom      1      10
Kate     1      60
Ali      1      70
Tom      2      60
Ali      2      70
Kate     2      100
Ali      3      90
Kate     3      100
Tom      3      140
like image 123
Yogesh Sharma Avatar answered Oct 19 '22 09:10

Yogesh Sharma


with cte as
(select *
 from
  (select distinct customer from myTable ) c
  cross join ( values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) t(month))

select cte.customer, cte.month, 
sum(myTable.amount) over (partition by cte.customer order by cte.month) as cumamount
from cte left join myTable
on cte.customer = myTable.customer and cte.month = myTable.month
order by  cte.month, cte.customer desc
like image 43
kc2018 Avatar answered Oct 19 '22 11:10

kc2018