BookmarkSubscribeRSS Feed
SASPhile
Quartz | Level 8

Table A has Id and Process_dt. Table B has Id,Trans_dt,Amount.

How to get number of transactions for each id whose transactions happened in last 30 days of the process_dt and next 30 days of the process_dt and their sum of amount as well.

id  present  no.of trans_under_30   no.of_trans_next_30   total_amount

Column present gives info 'Y' 'N' ,if the id is present in table A or not . Above are columns in the final table required.

8 REPLIES 8
Ksharp
Super User

SQL can do that. Showing your data and the final output will explain your question more clear.

Ksharp

SASPhile
Quartz | Level 8

Table A

id             process_dt

11            06JUN2012

12           15AUG2012

13            01SEP2012

Table B

id           Trans_dt              Amount

11          05/15/2012          50

11          05/31/2012          30

11          06/30/012            40

11          07/01/2012          70

12          08/31/2012           50

final table:

id            present              trans_before_30_days              trans_next_30days                     Amount_before        amount_after

11             Y                          2                                             2                                           80                          110

12             Y                          0                                              1                                            0                             50

13             N                          0                                              0                                            0                              0

Ksharp
Super User

OK.

data a;
input id             process_dt : date9.;
format process_dt  date9.;
cards;
11            06JUN2012
12           15AUG2012
13            01SEP2012
;
run;

data b;
input id           Trans_dt    : mmddyy10.          Amount;
format Trans date9.;
cards;
11          05/15/2012          50
11          05/31/2012          30
11          06/30/012            40
11          07/01/2012          70
12          08/31/2012           50
;
run;
proc sql;
create table want as
 select id,case when id in (select distinct id from b) then 'Y' else 'N' end as present,
        (select count(*) from b where a.id=b.id and b.Trans_dt between a.process_dt-30 and a.process_dt) as before,
        (select count(*) from b where a.id=b.id and b.Trans_dt between a.process_dt and a.process_dt+30) as after,
        coalesce((select sum(Amount) from b where a.id=b.id and b.Trans_dt between a.process_dt-30 and a.process_dt),0) as amount_before,
        coalesce((select sum(Amount) from b where a.id=b.id and b.Trans_dt between a.process_dt and a.process_dt+30),0) as amount_after
  from a;
quit;

Ksharp

SASPhile
Quartz | Level 8

thanks Ksharp.

inner join can get this result?

Ksharp
Super User

I afraid you couldn't , the main problem is making PRESENT variable.

SASPhile
Quartz | Level 8

table b is a huge table.doing when id in (select distinct id from b) then 'Y' else 'N' end as present will be taking a long time,I believe.

Ksharp
Super User

Did you try ?

or need another data step(hash table) to get this variable firstly .

or split it into lots of small tables .

Message was edited by: xia keshan

Tom
Super User Tom
Super User

Try this.  Not sure how well SAS will be able to optimize this.

Idea is to combine the two and set binary flag for whether the event is before or after.  Then you can use that in a SUM aggregate function in the outer query. 

You need to think about where to count the case when TRANS_DT = PROCESS_DT.  Is that in the 30 days before or the 30 days after?

I am not sure how you want to calculate the PRESENT flag.  You might need to move the data range checking out of the ON condition for the full join and into a WHERE condition for the outer query depending one what you want to do with cases where it is in HAVE1 but there are no dates in the 60 day window in HAVE2.

data have1;

input id process_dt : date9.;

format process_dt date9.;

cards;

11 06JUN2012

12 15AUG2012

13 01SEP2012

run;

data have2;

input id Trans_dt : mmddyy10. Amount;

format Trans_dt date9.;

cards;

11 05/15/2012 50

11 05/31/2012 30

11 06/30/2012 40

11 07/01/2012 70

12 08/31/2012 50

run;


proc sql;

create table want as

select id

     , max(c.present) as present

     , sum(c.before) as n_before

     , sum(c.after ) as n_after

     , coalesce(sum( c.amount * c.before ),0) as sum_before

     , coalesce(sum( c.amount * c.after  ),0) as sum_after

from (

  select coalesce(a.id,b.id) as id

       , (a.process_dt > b.trans_dt > .) as before

       , (. < a.process_dt < b.trans_dt) as after

       , case when (b.id is null) then 'N' else 'Y' end as present

       , b.amount

  from have1 a

       full join have2 b

       on a.id = b.id and (b.trans_dt between a.process_dt - 30 and a.process_dt + 30)

      ) c

group by 1

order by 1

;

quit;

proc print; run;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 2369 views
  • 3 likes
  • 3 in conversation