BookmarkSubscribeRSS Feed
Ram4sas
Fluorite | Level 6

Hi,

I have below data

AccountTypeSalary
3451100
3491200
4351500
65419000
65426000
654 3000
987115000
98729000
987 6000
8761400
4561200

from above data, i want extract into new table only account records which Account having type in(1,2) with third row which show difference for salary amount.

i want extract account details which contain type in(1, 2) and third row for salary difference, don't want account which contain only type =1

AccountTypeSalary
65419000
65426000
654 3000
987115000
98729000
987 6000

i have tried to extract with multiple trials, but not getting required output.

i tired with

data want;

set have;

retain account;

where type in (1,2,.);

run;

which gives all records.

and tried with this code

proc sort data=have;

by Account type;

run;

data want;

set have;

by account type;

if first.account and last.account then output;

run;

this code result giveing result output all five records except required 6 records for account 654(3 Records) and 987(3 records).

can you suggest how to get the requried output from having data?

Thank you very much

16 REPLIES 16
art297
Opal | Level 21

I think that the following will extract the records that you want:

proc sort data=have;

  by Account;

run;

data want (drop=t t1 t2 t3);

  do until (last.Account);

    set have;

    by Account;

    if type eq 1 then t1=1;

    else if type eq 2 then t2=1;

    else if missing(type) then t3=1;

    if last.Account then if t1 and t2 and t3 then t=1;

  end;

  do until (last.Account);

    set have;

    by Account;

    if t then output;

  end;

run;

Ram4sas
Fluorite | Level 6

HI Arthur,

thank you for reply and output coming like

AccountTypeSalary
654 3000
65419000
65426000
987 6000
987115000
98729000

can i populate type eq missing below to to record of type eq 2 as the type eq missing record carry difference value for type 1-2(mean 9000-6000=3000.

i mean i am looking for to generate output like below

AccountTypeSalary
65419000
65426000
654 3000
987115000
98729000
987 6000

thank you very much for your reply .

art297
Opal | Level 21

The code I suggested would not have changed the order of the type=missing records, thus your data was either not arranged as shown in your example or you added type to proc sort.  Apparently it was the former and, in that case, using KSharp's suggested proc sql code will provide your best solution.

Ksharp
Super User

Suppose there are only 1,2,. three value in type variable.

data have;
input Account     Type     Salary;
cards;
345     1     100
349     1     200
435     1     500
654     1     9000
654     2     6000
654     .     3000
987     1     15000
987     2     9000
987     .     6000
876     1     400
456     1     200
;
run;
proc sql;
 create table want as 
  select * from have 
   group by Account
    having sum(type=1)=1 and sum(type=2)=1 and sum(type=.)=1
     order by Account,missing(type);
quit;

Xia Keshan

Message was edited by: xia keshan

Ram4sas
Fluorite | Level 6

Hi Ksharp,

thank you for reply, the output coming like this with your code

AccountTypeSalary
65426000
65419000
6543000
98729000
987115000
987 6000

but the type value should populate type 1 in first record, then 2 in second record and finally missing as its carry the difference value for type 1-2(9000-6000=3000).

can i get output like this

AccountTypeSalary
65419000
65426000
654 3000
987115000
98729000
987 6000
Ksharp
Super User

Sure.

proc sql;

create table want as

  select * from have

   group by Account

    having sum(type=1)=1 and sum(type=2)=1 and sum(type=.)=1

     order by Account,missing(type),Type;

quit;

Xia Keshan

Ram4sas
Fluorite | Level 6

Hi Ksharp,

Thank you once again..

I tried this code, its working for above sample data.

but when i tried to do create table with my actual data where Account and Type columns are string not number.

-------------------------------------------------------------------------------------------

proc sql;

create table want as

  select Account, Type from have

   group by Account

    having sum(type='1')=1 and sum(type='2')=1 and sum(type=' ')=1

     order by Account,missing(type),Type;

quit;

-----------------------------------------------------------------------------------------------

its giving 0 records in output.

in log it says that :

The query as specified involves ordering by an item that doesn't appear in its SELECT Clause.

The query requires remerging summary statistics back with the original data.

why its not working for this case..

Ram4sas
Fluorite | Level 6

Hi Ksharp,

Its working fine.. thank you very much once again

Ram4sas
Fluorite | Level 6

HI Ksharp,

I got stuck up with one issue here. the above code is working fine for records where the account has type 1 and 2 values from date.

we are giving output based on record_gen dates users select date on which date user wanna see account details.

the account and type values being populating on different dates like for account 001, type =1 is available on 01JUN2014 record_gen date and account 001 and type=2 is avalaible on 25JUN2014 record_gen Date.

when user select 25JUN2014 date to see the account records, no records are getting retrived, because for account 001& type=2 is there for 25JUN2014.

account 001 and type=1 record availbel for previous date 01JUN2014.

How to get the both records for same account record contain type values in different dates?

thanks...

Ksharp
Super User

OK.You said you output data based on record_gen dates , But you didn't post your sample data . I just describe data like this :

data have;
input Account     Type     Salary  record_gen : date9. ;
format record_gen date9.;
cards;
345     1     100 25JUN2014
349     1     200 25JUN2014
435     1     500  25JUN2014
654     1     9000   01JUN2014
654     2     6000   25JUN2014 
654     .     3000   01JUN2014
987     1     15000     25JUN2014
987     2     9000 25JUN2014
987     .     6000  25JUN2014
876     1     400  01JUN2014
456     1     200  01JUN2014
;
run;

%let date= 25JUN2014 ;
proc sql;
create table want as
select * from have 
 where Account in (
  select distinct Account from have where      record_gen="&date"d

  intersect

  select distinct Account from have
   group by Account
    having sum(type=1)=1 and sum(type=2)=1 and sum(type=.)=1

)
     order by Account,missing(type),Type;
quit;

Xia Keshan

Ram4sas
Fluorite | Level 6

Hi,

data is below for your information

Rec_Gen_Dt      Account      Type      salary

01JUN2014        001               01          230    

01JUN2014        002               01          678   

01JUN2014        003               01          980

25JUN2014        001               02          234

25JUN2014        002               02          670

25JUN2014        003               02          980    

we set up stored process code with dynamic prompt to provide access to user to select record_gen_dt values.

when user select date prompt value 25JUN2014, below report should come.

Account      Type      salary

001               01          230 

001               02          234 

002               01          678

002               02          670

003               01          980

003               02          980

I hope this would help to uinderstand my query.

thank you in advace.

Ksharp
Super User

OK. My code should help you a little bit .

data have;
input Rec_Gen_Dt   : date9.   Account      Type      salary     ;
format Rec_Gen_Dt date9.;
cards;
01JUN2014        001               01          230    
01JUN2014        002               01          678   
01JUN2014        003               01          980
25JUN2014        001               02          234
25JUN2014        002               02          670
25JUN2014        003               02          980    
;
run;




%let date= 25JUN2014 ;
proc sql;
select * from have 
 where Account in (
  select distinct Account from have where      Rec_Gen_Dt="&date"d

  intersect

  select distinct Account from have
   group by Account
    having sum(type=1)=1 and sum(type=2)=1 

)
     order by Account,missing(type),Type;
quit;


Xia Keshan

Ram4sas
Fluorite | Level 6

HI Keshan,

the above code works for 25JUN2014 date prompt as the accounts got salary changed on 25JUN2014 (as excepted to retrieve account details which got changed their Salary in last 25 days 01JUN2014).

But when I select 01JUN2014 value in prompt, it gives out put for account numbers with records type=2 which actually got generate/type changed on 20JUN2014 or 25JUN2014, these records supposed to not to retrieve for 01JUN2014 prompt values, and 01Jun2014 date prompt it has to retrieve records from last month 05APR2014 if records available else no output.

I want to restrict to not show 20/25JUN2014 record_gen_date records (type=2) when I select 01JUN2014 and run the code.

Basic query is when I select date prompt, it should full account records for last 25 days with type=1 & 2, not for future dates records.

I hope I had placed query correctly. reply text if query not cache.

thank you very much.

Ksharp
Super User

You only want query obs last 25 days with type=1 & 2  ? what if one of an Account's obs(either type=1 or type=2) is out of this range ,this Account will not be printed either ? if so .

data have;
input Rec_Gen_Dt   : date9.   Account      Type      salary     ;
format Rec_Gen_Dt date9.;
cards;
01JUN2014        001               01          230    
01JUN2014        002               01          678   
01JUN2014        003               01          980
25JUN2014        001               02          234
25JUN2014        002               02          670
25JUN2014        003               02          980    
;
run;




%let date= 01JUN2014  ;
proc sql;
select * from have 
 where Account in (
  select distinct Account from have where      Rec_Gen_Dt="&date"d

  intersect

  select distinct Account from have
   where Rec_Gen_Dt between "&date"d-25  and "&date"d
    group by Account
     having sum(type=1)=1 and sum(type=2)=1 

)
     order by Account,missing(type),Type;
quit;

Xia Keshan

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!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 16 replies
  • 2473 views
  • 0 likes
  • 4 in conversation