BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
itsalexis
Calcite | Level 5

Hi,

I have been searching for a solution to this for a while and my googling hasn't resulted in anything tangible. I hope someone here can help.

I have 2 datasets (all data is made up but the gist should be there):

 

1. Transaction_Tbl - the source dataset that contains transactional data of call reps for selected dates and call durations:

Transaction_Tbl     
ID_NUMEMP_NMDATECALL_STARTCALL_ENDCALL_DUR
000121Mark6/4/20234:30 PM4:32 PM2
000121Mark8/15/20238:30 AM8:31 AM1
000121Mark9/6/20239:15 AM9:18 AM3
000121Mark5/6/202410:05 AM10:06 AM1
000121Mark6/10/20242:22 PM2:23 PM1
000122Jessie4/29/20238:45 AM8:55 AM10
000122Jessie11/29/202311:15 AM11:30 AM15
000122Jessie12/8/20231:23 PM1:40 PM17
000122Jessie2/16/20241:40 PM1:55 PM15
000123James2/8/202312:10 PM12:20 PM10
000123James2/22/20232:33 PM2:55 PM22
000123James1/21/20244:12 PM4:19 PM7
000124Felicia5/23/20243:42 PM3:55 PM13
000127Henry1/2/20239:02 AM9:10 AM8
000127Henry3/18/20239:50 AM10:00 AM10
000127Henry4/21/202310:05 AM10:20 AM15
000127Henry10/26/20231:22 PM1:27 PM5
000127Henry11/12/20232:00 PM2:04 PM4

 

2. Card_Tbl - The supplemental dataset that shows what "card" the rep held between a certain date range. The card changes annually based on performance and defines the expected call duration at the card level:

 

Card_Tbl     
ID_NUMEMP_NMEFF_DTEND_DTCARDCARD_DESC
000121Mark1/1/202012/31/2020GREENComplete calls within 15 minutes.
000121Mark1/1/202112/31/2021BLUEComplete calls within 5 minutes.
000121Mark1/1/202212/31/2022ORANGEComplete calls within 8 minutes.
000121Mark1/1/202312/31/2023GREENComplete calls within 15 minutes.
000121Mark1/1/202412/31/2024BLUEComplete calls within 5 minutes.
000122Jessie1/1/202212/31/2022GREENComplete calls within 15 minutes.
000122Jessie1/1/202312/31/2023GREENComplete calls within 15 minutes.
000122Jessie1/1/202412/31/2024GREENComplete calls within 15 minutes.
000123James7/1/20226/30/2023GREENComplete calls within 15 minutes.
000123James7/1/20236/30/2024ORANGEComplete calls within 8 minutes.
000123James7/1/20246/30/2025YELLOWComplete calls within 10 minutes.
000124Felicia3/1/20242/28/2025GREENComplete calls within 15 minutes.
000127Henry1/1/202312/31/2023GREENComplete calls within 15 minutes.
000127Henry1/1/202412/31/2024BLUE

Complete calls within 5 minutes.

 

I am currently reviewing the rep call duration manually by dumping the data to excel and adding the relevant card color from Card_tbl and determining a pass or fail if the call duration meets expectation.

 

The table i'd like to get by using SAS instead of manual work in excel is this (and complete a full population review vs a manual one):

ID_NUM, EMP_NM, DATE, and CALL_DUR from Transaction_Tbl

CARD from Card_Tbl based on the date

RESULT is new to the want_tbl and will show pass/fail depending on CALL_DUR and CARD value

Want_tbl     
ID_NUMEMP_NMDATECALL_DURCARDRESULT
000121Mark6/4/20232GREENPASS
000121Mark8/15/20231GREENPASS
000121Mark9/6/20233GREENPASS
000121Mark5/6/20241BLUEPASS
000121Mark6/10/20241BLUEPASS
000122Jessie4/29/202310GREENPASS
000122Jessie11/29/202315GREENPASS
000122Jessie12/8/202317GREENFAIL
000122Jessie2/16/202415GREENPASS
000123James2/8/202310GREENPASS
000123James2/22/202322GREENFAIL
000123James1/21/20247ORANGEPASS
000124Felicia5/23/202413GREENPASS
000127Henry1/2/20238GREENPASS
000127Henry3/18/202310GREENPASS
000127Henry4/21/202315GREENPASS
000127Henry10/26/20235GREENPASS
000127Henry11/12/20234GREEN

PASS

 

I cannot figure out how to grab the applicable CARD value from the Card_Tbl as it applies to the ID_NUM/date in the Transaction_Tbl.

 

Thank You for your time and expertise.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

First let's convert your listings into actual SAS datasets.  Let's call them TRANSACTIONS and CARDS.

Spoiler
data transactions;
  input ID_NUM $ EMP_NM $ DATE :mmddyy. (CALL_START CALL_END) (:time.) CALL_DUR ;
  format date yymmdd10. call_start call_end tod5. ;
cards;
000121 Mark 6/4/2023 4:30PM 4:32PM 2
000121 Mark 8/15/2023 8:30AM 8:31AM 1
000121 Mark 9/6/2023 9:15AM 9:18AM 3
000121 Mark 5/6/2024 10:05AM 10:06AM 1
000121 Mark 6/10/2024 2:22PM 2:23PM 1
000122 Jessie 4/29/2023 8:45AM 8:55AM 10
000122 Jessie 11/29/2023 11:15AM 11:30AM 15
000122 Jessie 12/8/2023 1:23PM 1:40PM 17
000122 Jessie 2/16/2024 1:40PM 1:55PM 15
000123 James 2/8/2023 12:10PM 12:20PM 10
000123 James 2/22/2023 2:33PM 2:55PM 22
000123 James 1/21/2024 4:12PM 4:19PM 7
000124 Felicia 5/23/2024 3:42PM 3:55PM 13
000127 Henry 1/2/2023 9:02AM 9:10AM 8
000127 Henry 3/18/2023 9:50AM 10:00AM 10
000127 Henry 4/21/2023 10:05AM 10:20AM 15
000127 Henry 10/26/2023 1:22PM 1:27PM 5
000127 Henry 11/12/2023 2:00PM 2:04PM 4
;

data cards;
  infile cards truncover;
  input ID_NUM $ EMP_NM $ (EFF_DT END_DT) (:mmddyy.) CARD $ CARD_DESC $50.;
  format EFF_DT END_DT yymmdd10.;
cards;
000121 Mark 1/1/2020 12/31/2020 GREEN Complete calls within 15 minutes.
000121 Mark 1/1/2021 12/31/2021 BLUE Complete calls within 5 minutes.
000121 Mark 1/1/2022 12/31/2022 ORANGE Complete calls within 8 minutes.
000121 Mark 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000121 Mark 1/1/2024 12/31/2024 BLUE Complete calls within 5 minutes.
000122 Jessie 1/1/2022 12/31/2022 GREEN Complete calls within 15 minutes.
000122 Jessie 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000122 Jessie 1/1/2024 12/31/2024 GREEN Complete calls within 15 minutes.
000123 James 7/1/2022 6/30/2023 GREEN Complete calls within 15 minutes.
000123 James 7/1/2023 6/30/2024 ORANGE Complete calls within 8 minutes.
000123 James 7/1/2024 6/30/2025 YELLOW Complete calls within 10 minutes.
000124 Felicia 3/1/2024 2/28/2025 GREEN Complete calls within 15 minutes.
000127 Henry 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000127 Henry 1/1/2024 12/31/2024 BLUE Complete calls within 5 minutes.
;

It is much easier to do matches on ranges with SQL syntax, so let's do a left join of TRANSACTIONS with CARDS so we have all of the information on the same observations.  We can then extract the target duration from the descriptive text and convert to a number that we can compare to the call duration.

proc sql;
create table want as 
  select a.*
       , b.card
       , b.card_desc
       , input(scan(b.card_desc,-2,' '),32.) as target
       , (a.CALL_DUR between 0 and calculated target) as satisfied
  from transactions a
  left join cards b
    on a.ID_NUM = b.ID_NUM
    and a.DATE between b.EFF_DT and b.END_DT
  order by a.ID_NUM, a.date, a.call_start
;
quit;

Results

Tom_0-1729040682091.png

 

View solution in original post

2 REPLIES 2
Kurt_Bremser
Super User
proc sql;
create table want as
  select
    t1.id_num,
    t1.emp_nm,
    t1.date,
    t1.call_dur,
    t2.card
  from trans t1 left join card t2
  on t1.id_num = t2.id_num and t2.eff_dt le t1.date le t2.end_dt
;
quit;

You can then code the condition in a DATA step, or you can integrate it in the SQL if you're versed with SQL CASE.

Tom
Super User Tom
Super User

First let's convert your listings into actual SAS datasets.  Let's call them TRANSACTIONS and CARDS.

Spoiler
data transactions;
  input ID_NUM $ EMP_NM $ DATE :mmddyy. (CALL_START CALL_END) (:time.) CALL_DUR ;
  format date yymmdd10. call_start call_end tod5. ;
cards;
000121 Mark 6/4/2023 4:30PM 4:32PM 2
000121 Mark 8/15/2023 8:30AM 8:31AM 1
000121 Mark 9/6/2023 9:15AM 9:18AM 3
000121 Mark 5/6/2024 10:05AM 10:06AM 1
000121 Mark 6/10/2024 2:22PM 2:23PM 1
000122 Jessie 4/29/2023 8:45AM 8:55AM 10
000122 Jessie 11/29/2023 11:15AM 11:30AM 15
000122 Jessie 12/8/2023 1:23PM 1:40PM 17
000122 Jessie 2/16/2024 1:40PM 1:55PM 15
000123 James 2/8/2023 12:10PM 12:20PM 10
000123 James 2/22/2023 2:33PM 2:55PM 22
000123 James 1/21/2024 4:12PM 4:19PM 7
000124 Felicia 5/23/2024 3:42PM 3:55PM 13
000127 Henry 1/2/2023 9:02AM 9:10AM 8
000127 Henry 3/18/2023 9:50AM 10:00AM 10
000127 Henry 4/21/2023 10:05AM 10:20AM 15
000127 Henry 10/26/2023 1:22PM 1:27PM 5
000127 Henry 11/12/2023 2:00PM 2:04PM 4
;

data cards;
  infile cards truncover;
  input ID_NUM $ EMP_NM $ (EFF_DT END_DT) (:mmddyy.) CARD $ CARD_DESC $50.;
  format EFF_DT END_DT yymmdd10.;
cards;
000121 Mark 1/1/2020 12/31/2020 GREEN Complete calls within 15 minutes.
000121 Mark 1/1/2021 12/31/2021 BLUE Complete calls within 5 minutes.
000121 Mark 1/1/2022 12/31/2022 ORANGE Complete calls within 8 minutes.
000121 Mark 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000121 Mark 1/1/2024 12/31/2024 BLUE Complete calls within 5 minutes.
000122 Jessie 1/1/2022 12/31/2022 GREEN Complete calls within 15 minutes.
000122 Jessie 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000122 Jessie 1/1/2024 12/31/2024 GREEN Complete calls within 15 minutes.
000123 James 7/1/2022 6/30/2023 GREEN Complete calls within 15 minutes.
000123 James 7/1/2023 6/30/2024 ORANGE Complete calls within 8 minutes.
000123 James 7/1/2024 6/30/2025 YELLOW Complete calls within 10 minutes.
000124 Felicia 3/1/2024 2/28/2025 GREEN Complete calls within 15 minutes.
000127 Henry 1/1/2023 12/31/2023 GREEN Complete calls within 15 minutes.
000127 Henry 1/1/2024 12/31/2024 BLUE Complete calls within 5 minutes.
;

It is much easier to do matches on ranges with SQL syntax, so let's do a left join of TRANSACTIONS with CARDS so we have all of the information on the same observations.  We can then extract the target duration from the descriptive text and convert to a number that we can compare to the call duration.

proc sql;
create table want as 
  select a.*
       , b.card
       , b.card_desc
       , input(scan(b.card_desc,-2,' '),32.) as target
       , (a.CALL_DUR between 0 and calculated target) as satisfied
  from transactions a
  left join cards b
    on a.ID_NUM = b.ID_NUM
    and a.DATE between b.EFF_DT and b.END_DT
  order by a.ID_NUM, a.date, a.call_start
;
quit;

Results

Tom_0-1729040682091.png

 

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 2 replies
  • 1076 views
  • 3 likes
  • 3 in conversation