-3

I have a table like this one:

Table as is

I would like to calculate cumulative sum for column "total" for each cust_id in last x months, based on date_ini and today, so my output would be :

desired output

Could you help me doing this in sas / proc sql?

Thanks!

Stu
  • 30,392
  • 6
  • 14
  • 33
  • Sorry, what do you mean? – user8419142 Apr 29 '21 at 15:39
  • 2
    Please post data as text not photographs. Please show what code you tried and explain how it did not get what you need. – Tom Apr 29 '21 at 15:59
  • @user8419142 . . . This is probably easier using a data step. – Gordon Linoff Apr 29 '21 at 16:07
  • To help you we'd have to type out your data, then code a solution. You also didn't show anything you've tried so far per the SO guidelines on how to ask a question [ask]. Please post your data as text at minimum and include what you've tried so far. Also explain why you require SQL since a PROC or DATA step are more efficient here. – Reeza Apr 29 '21 at 16:08

2 Answers2

1

Cumulative results can be computed with SQL using a self-join with grouping and range limiting criteria.

Example:

data have;
  call streaminit(2021);
  do id = 1 to 10;
    do date = '01jan2017'd to '31dec2020'd;
      x = rand('integer', 10);
      if rand('uniform') < 0.20 then output;
    end;
  end;
  format date date9.;
run;

proc sql;
  create table want as
  select 
    self.id,
    self.date,
    self.x,
    count(earlier.date) as date_count,
    sum(earlier.x) as x_sum_36mo
  from 
    have as self
  left join 
    have as earlier
  on
    self.id = earlier.id and
    earlier.date between self.date and intnx('month', self.date, -36)
  group by
    self.id, self.date, self.x
  ;

A DOW loop in SAS DATA step is more performant, and multiple cumulative periods can be computed during a single pass through the data. Such code can be found in earlier questions.

Richard
  • 25,390
  • 3
  • 25
  • 38
1

It just looks like you want use CASE to decide whether the TOTAL contributes to your new sum.

So assuming your reference date is the current date you might use something like this.

create table want as
  select cust_id
       , sum(case
             when (date_ini >= intnx('month',today(),-1,'b') then total
             else 0 end) as total_last_month
       , sum(case
             when (date_ini >= intnx('month',today(),-36,'b') then total
             else 0 end) as total_last_36months
  from have
  group by cust_id
;

But I am not sure I would call those cumulative sums.

Tom
  • 47,574
  • 2
  • 16
  • 29
  • Thanks!! What if instead of today() i want to use as reference date the month with format "YYYYMM" ? – user8419142 May 06 '21 at 10:36
  • To have a date you need a day of the month, usually the first day of the month is used and that should work with INTNX(). To specify a data literal in SAS you need it in a style that DATE informat can read. Such as `'01MAY2021'd`. If you have a date variable on the same observation you can reference that. If your variable is character like `'202105'` then convert it to a date using the input() function. `input(chdatevar,yymmn6.)` – Tom May 06 '21 at 11:19
  • Thank you for the help!! The problem is that I want to sum total_last_36months but within a fix month that i get from the date_ini, so something like: for each YYYYMM (created based on date_ini) sum total if date_ini is between date_ini-36 months and date_ini. Is it clear? Don't know if I expressed myself clearly :) – user8419142 May 06 '21 at 13:11
  • https://stackoverflow.com/questions/67420988/sql-statment-syntax-from-teradata-to-proc-sql here's the question better explained :) – user8419142 May 06 '21 at 15:12