BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
TheNovice
Quartz | Level 8

Hi all,


I have to solve this using proc sql because it will then be converted to a sql script for automation and needs to be as close as possible (just how things work here). 


My dataset has duplicate records like below with different dates. I need to join to a second table where b.date > a.date. But i only want to join to the closest match to b.date which is the max (a.date)

 

Table a 
BANcol_date
12320-Jun-20
12321-Jul-20

 

Table b 
statusstatus_date
r20-Aug-20

 

to get   

Table a   
BANcol_datestatusstatus_date
12320-Jun-20  
12321-Jul-20r20-Aug-20

 

Would appreciate any and all guidance. thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Shmuel
Garnet | Level 18

@TheNovice wrote:
Apologies, yes, the join key would be ban

According to above I have added BAN to table b.

Next code is tested:

data table_a;
 input ban col_date :date9.;
 format col_date date9.;
cards;
123 20-jun-20
123 21-jul-20
; run;

data table_b;
 input ban status $ status_date :date9.;
 format status_date date9.;
cards;
123 r 20-aug-20
; run;

proc sql;
 create table want(drop=dif_date min_date) as
 select a.ban, a.col_date,
        b.status_date - a.col_date as dif_date,
        min(calculated dif_date) as min_date,
        case when calculated dif_date = calculated min_date
             then b.status 
             else  ' ' end as status ,
        case when calculated dif_date = calculated min_date
             then b.status_date 
             else  .   end as status_date format=date9.
 from table_a as a 
 left join table_b as b 
 on a.ban = b.ban 
 group by a.ban 
;
quit;

View solution in original post

8 REPLIES 8
PGStats
Opal | Level 21

There is no BAN in table b?

PG
TheNovice
Quartz | Level 8
Apologies, yes, the join key would be ban
andreas_lds
Jade | Level 19

@TheNovice wrote:
Apologies, yes, the join key would be ban

Then, again: why is the variable BAN not in the second table?

Shmuel
Garnet | Level 18

@TheNovice wrote:
Apologies, yes, the join key would be ban

According to above I have added BAN to table b.

Next code is tested:

data table_a;
 input ban col_date :date9.;
 format col_date date9.;
cards;
123 20-jun-20
123 21-jul-20
; run;

data table_b;
 input ban status $ status_date :date9.;
 format status_date date9.;
cards;
123 r 20-aug-20
; run;

proc sql;
 create table want(drop=dif_date min_date) as
 select a.ban, a.col_date,
        b.status_date - a.col_date as dif_date,
        min(calculated dif_date) as min_date,
        case when calculated dif_date = calculated min_date
             then b.status 
             else  ' ' end as status ,
        case when calculated dif_date = calculated min_date
             then b.status_date 
             else  .   end as status_date format=date9.
 from table_a as a 
 left join table_b as b 
 on a.ban = b.ban 
 group by a.ban 
;
quit;
Ksharp
Super User
data table_a;
 input ban col_date :date9.;
 format col_date date9.;
cards;
123 20-jun-20
123 21-jul-20
; run;

data table_b;
 input ban status $ status_date :date9.;
 format status_date date9.;
cards;
123 r 20-aug-20
; run;

proc sql;
 create table want as
 select a.ban, a.col_date,

 case when abs(a.col_date-b.status_date)=
 min(abs(a.col_date-b.status_date)) then b.status
 else ' ' end as status
 ,
 case when abs(a.col_date-b.status_date)=
 min(abs(a.col_date-b.status_date)) then b.status_date
 else . end as status_date format=date9.

 from table_a as a 
 left join table_b as b 
 on a.ban = b.ban ;
 quit;
PGStats
Opal | Level 21

I think @Ksharp 's answer doesn't quite answer the question. This might do better:

 

data a;
 input ban col_date :date9.;
 format col_date date9.;
cards;
123 20-jun-20
123 21-jul-20
567 20-jun-20
567 21-jul-20
;

data b;
 input ban status $ status_date :date9.;
 format status_date date9.;
cards;
123 r 20-aug-20
456 r 20-aug-20
;

proc sql;
 
 select a.ban, col_date,

 case when col_date = max(col_date) then status
 else ' ' end as status
 ,
 case when col_date = max(col_date) then status_date
 else . end as status_date format=date9.

 from a 
 left join b 
 on a.ban = b.ban and status_date > col_date
 group by a.ban;
 quit;

image.png

PG
TheNovice
Quartz | Level 8
Thank you all so much. all the solutions work 🙂 I will tag the first one with the accept then. thanks again
Ksharp
Super User
PG,
Yes. I misunderstood something in original post .

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 8 replies
  • 3723 views
  • 1 like
  • 5 in conversation