BookmarkSubscribeRSS Feed
Burakgns
Fluorite | Level 6

Hello,

proc sql;

create table table_2 as

select * from table_2022  (I want the table name to change automatically compared to 3.6 and 12 months ago.)

where year = 2022 and month = 08; (I want these fields to come automatically.)

 

 

proc sql;

create table table_1 as 

select * from table_2023 (I want the table name to change automatically compared to 3.6 and 12 months ago.)

where year = 2023 and month in (05,03)  (I want these fields to come automatically.)

 

I can give an example like that. I dont want to write year and month manuel. Would we try to write it like symput? As each month changes, I want the month variables in the where constraint to change from manual to automation. Can we write this in one set instead of writing two different sets of code?

4 REPLIES 4
Tom
Super User Tom
Super User

In your two examples there are three places where the code is changing.

So it seems you might benefit from a macro with three input parameters.

%macro subset(year,months,out);
proc sql;
create table &out as
select * from table_&year 
where year = &year
   and month in (&months)
; 
%mend;
%subset(2022,08,table_1)
%subset(2023,05 03,table_2)

Note don't bother using comma as the delimiter in the list of months, it will just make it harder to pass a value to the macro, as the IN operator in SAS allows you use either commas or spaces as the delimiter in the list of values.

Not sure why you have leading zeros on numbers, but those will not matter.  

Not sure why you have to select by the value of YEAR if the dataset name already has the year value in its name.  Is it possible that the dataset names TABLE_2023 has some observations where the value of YEAR is not 2023?  Why?

 

If you want to automate you need to spell out the rules for how to translate from the concept of "3 months ago" to one of those two SQL codes.  What is the rule for generating the values of YEAR?  What is the rule for generating the value of MONTHS you want to include?  What is the rule for generating the name of the output dataset? 

 

How to you want to encode the concept of "3 months ago" and "6 months ago"?  Do you just want to use the digit strings of 3 6 and 12 ?

Burakgns
Fluorite | Level 6

I do not have to write the code in sql language. The reason I put the variable year is because there is a table specific to each year. table_2023 only contains data for 2023. I want to use data for the year and the months I want (3,6 and 12). Instead of writing this manually, I want to write a macro like in the example you gave. But I'm not good at macro writing. This example was written for September 2023. In the future (April 2024 for example), when I want data from 3 months ago, I want to automatically assign table_2024 to 6 months and 12 months ago when I want table_2022.

Tom
Super User Tom
Super User

So if have as input a number representing a number of months you can use that with INTNX() to find a date that is that number of months ago.

Once you have a date you can calculate the year of that date and the month of that date.

 

I do not understand what you mean by testing for more than one month value.    Do you mean you just want the data for the three individual months that are 3, 6 and 12 months ago?

 

You keep not explaining what your data actually looks like.  Do you have a DATE variable?  Or do you have YEAR and MONTH variables?  Or do you have something else?  Perhaps some character variable?

 

Since you implied you have YEAR and MONTH variables you could do:

%macro test;
%local today year date month fyear lyear;
%let today=%sysfunc(today());
%let fyear=%sysfunc(intnx(month,&today,-12),year.);
%let lyear=%sysfunc(intnx(month,&today,-3),year.);
data want ;
  set mylib.table_&fyear - mylib.table_&lyear ;
  where 
%let date=%sysfunc(intnx(month,&today,-12));
      (year = %sysfunc(year(&date)) and month=%sysfunc(month(&date)) )
%let date=%sysfunc(intnx(month,&today,-6));
   or (year = %sysfunc(year(&date)) and month=%sysfunc(month(&date)) )
%let date=%sysfunc(intnx(month,&today,-3));
   or (year = %sysfunc(year(&date)) and month=%sysfunc(month(&date)) )
   ;
run;
Reeza
Super User

This isn't necessarily shorter, but is automated. Change the month at the top - which could also be derived from a system date if this is run every month (e.g. today())

 

%let reportMonth = 202304;

data _null_;
start_date = input("&reportMonth", yymmn6.);

do i=3, 6, 12;
    date = intnx('month', start_date, -1*i, 'b');
    dset_text = catt("table_", year(date), ' (where=(month=', month(date), '))');
    call symputx(catt('source', put(i, 8. -l)), dset_text);
end;

run;


data want;
set &source3. &source6. &source12.;
run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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