BookmarkSubscribeRSS Feed
new_sas_user_4
Quartz | Level 8

Hi Everyone,

 

I want number series for the past one year for subsetting data:

Eg: If I am in July, I want to get the past 12 months data.

 

Proc sql;

create table A as select * from B where (month in (1,2,3,4,5,6) and year in (2019)) or (month in (7,8,9,10,11,12) and year in (2018));

run;

 

The month and year fields are numeric in table "B".

How can this be done?

 

Thank you 🙂

 

 

11 REPLIES 11
ballardw
Super User

@new_sas_user_4 wrote:

Hi Everyone,

 

I want number series for the past one year for subsetting data:

Eg: If I am in July, I want to get the past 12 months data.

 

Proc sql;

create table A as select * from B where (month in (1,2,3,4,5,6) and year in (2019)) or (month in (7,8,9,10,11,12) and year in (2018));

run;

 

The month and year fields are numeric in table "B".

How can this be done?

 

Thank you 🙂

 

 


Did that code not work? As long as the from table name is a valid SAS data set and the variable names in the data a described that should work.

Reeza
Super User
What is the type and format on your date variables?

This can be done, but how depends on your data structure.
new_sas_user_4
Quartz | Level 8

This works fine, But I want to automate it so the next month ...say August 2019 I wont have to re-write :

Proc sql;

create table A as select * from B where (month in (1,2,3,4,5,6,7) and year in (2019)) or (month in (8,9,10,11,12) and year in (2018));

run;

 

The values for month and year should be filled in automatically in the code based on the month I am in!

Reeza
Super User

What is the type and format on your date variables?

 

It's much more efficient to use INTNX or INTCK instead of manually doing these calculations each month, but to do that you need to have a SAS date. Then it becomes.

 

where date between intnx('month', today(), 0, 'b') and intnx('month', today(), -12, 'b');

You'll probably need to tweak the elements a bit but in general that's a more robust method.

 


@new_sas_user_4 wrote:

This works fine, But I want to automate it so the next month ...say August 2019 I wont have to re-write :

Proc sql;

create table A as select * from B where (month in (1,2,3,4,5,6,7) and year in (2019)) or (month in (8,9,10,11,12) and year in (2018));

run;

 

The values for month and year should be filled in automatically in the code based on the month I am in!


 

ballardw
Super User

@Reeza wrote:

What is the type and format on your date variables?

 

It's much more efficient to use INTNX or INTCK instead of manually doing these calculations each month, but to do that you need to have a SAS date. Then it becomes.

 

where date between intnx('month', today(), 0, 'b') and intnx('month', today(), -12, 'b');

You'll probably need to tweak the elements a bit but in general that's a more robust method.

 


@new_sas_user_4 wrote:

This works fine, But I want to automate it so the next month ...say August 2019 I wont have to re-write :

Proc sql;

create table A as select * from B where (month in (1,2,3,4,5,6,7) and year in (2019)) or (month in (8,9,10,11,12) and year in (2018));

run;

 

The values for month and year should be filled in automatically in the code based on the month I am in!


 


Might want

where date between intnx('month', today(), 0, 'e') and intnx('month', today(), -12, 'b');

if the end of the current month is the goal.

Date values are generally preferred instead of separate month and year fields as a single value manipulates easily for many tasks.

If you don't have a day of the month then  pick a day to assume for such purposes and create it with 

date= mdy(month,1,year) for first day of the month. Other options are available if desired but which day needed would need to be known to modify code. 

Reeza
Super User
where date between intnx('month', today(), -13, 'b') and intnx('month', today(), -1, 'e');

Since it's from July 2018 to June 2019 it's likely the above.
novinosrin
Tourmaline | Level 20

Hello @new_sas_user_4  Follow this approach if you like,

 

/*Since you didn't provide a sample I create a sample have with year and month variables assuming you do not have a date variable*/
data have;
do year=2015 to 2020;
do month=1 to 12;
output;
end;
end;
run;

/*Create a look up table, this logic will dynamically create the last 12 months from he current month*/
data look_up;
k=12-month(today());
do month=month(today())-1 to 1 by -1;
year=year(today());
output;
end;
do month=12 to 12-k by -1;
year=year(today())-1;
output;
end;
keep month year;
run;


/*Straight forward Look up from your have on to the look up table and output the matches*/
data want ;
if _n_=1 then do;
   dcl hash H (dataset:'look_up') ;
   h.definekey  ("month","year") ;
   h.definedone () ;
end;
set have;
if h.check()=0;
run;
novinosrin
Tourmaline | Level 20

And if you truly understand the above,

 

The lookup table step  and the hash step can be combined into one. However , no biggie as you are only creating 12 records in the look up table, so may as well keep it as suggested previously

 

data want ;
if _n_=1 then do;
   dcl hash H () ;
   h.definekey  ("month","year") ;
   h.definedata ("month","year") ;
   h.definedone () ;
   k=12-month(today());
   do month=month(today())-1 to 1 by -1;
   year=year(today());
   h.add();
   end;
   do month=12 to 12-k by -1;
   year=year(today())-1;
   h.add();
   end;
end;
set have;
if h.check()=0;
drop k;
run;
new_sas_user_4
Quartz | Level 8

I think the solutions with intnx will work for my query...

 

I didnt understand this part @novinosrin  :

data want ;
if _n_=1 then do;
   dcl hash H (dataset:'look_up') ;
   h.definekey  ("month","year") ;
   h.definedone () ;

 

novinosrin
Tourmaline | Level 20

@new_sas_user_4  Yes if you do have a Date variable, you are better of using intnx. That's absolute!

 

The solution I gave you assumes you do not have a date variable. Also, as @Reeza  pointed out, you could help us to help you by providing a sample of what you have. That would not lead to assumptions.

novinosrin
Tourmaline | Level 20

The SQL equivalent of the above HASH would be

 


proc sql;
create table want as
select a.*
from have a inner join look_up b
on a. month=b.month and a.year=b.year;
quit; 

 

Again all of my suggestions assumes you do not have a date variable 

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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
  • 11 replies
  • 2884 views
  • 4 likes
  • 4 in conversation