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

I'm using the following precode in an Extract transformation:

%let extract_dttm = intnx('DTMONTH',DATETIME(),&back.,'E');

%put &extract_dttm;

The purpose of the Extract, if run today, is to extract all rows with extract_dttm between Valid_From_DTTM and Valid_From_DTTM

The &back parameter is -1, to designate the previous month.

When I run the Extract, %put &extract_dttm prints the text "intnx('DTMONTH',DATETIME(),-1,'E')" to the log. How do I turn this into a value? I need to be able to use it in this WHERE-statement:

&extract_dttm. BETWEEN Valid_From_DTTM AND Valid_From_DTTM

Thanks for your time. Smiley Happy

1 ACCEPTED SOLUTION

Accepted Solutions
RichardinOz
Quartz | Level 8

Here is the all-singing, all-dancing version

%macro Datelimit (back) ;

    %local set_dttm ;

    %Let set_dttm = %sysevalf(%sysfunc(intnx(DTMONTH,%sysfunc(DATETIME()),&back.,E))) ;

    %* no semiclolon on next line ;

    %Unquote(%Str(%')%sysfunc(Putn(&set_dttm, datetime20.))%str(%')DT)

%Mend ;

%Put Where extract_dttm Between %Datelimit(-3) and %Datelimit(-1) ;

Where extract_dttm Between '  31JUL2012:23:59:59'DT and '  30SEP2012:23:59:59'DT

Enjoy

Richard in Oz

View solution in original post

6 REPLIES 6
RichardinOz
Quartz | Level 8

You have a mix of Base and Macro:  the macro compiler will treat intnx as text.

Use %sysfunc to bring intnx into the macro compiler.  May also need %sysevalf

Try this

     %let extract_dttm = %sysevalf(%sysfunc(intnx(DTMONTH,%sysfunc(DATETIME()),&back.,E))) ;

     %put &extract_dttm;

Regards

Richard in Oz

RichardinOz
Quartz | Level 8

If you want to check the date,

     %Put %Sysfunc(putn(&extract_dttm, datetime.)) ;

30SEP12:23:59:59

RichardinOz
Quartz | Level 8

Here is the all-singing, all-dancing version

%macro Datelimit (back) ;

    %local set_dttm ;

    %Let set_dttm = %sysevalf(%sysfunc(intnx(DTMONTH,%sysfunc(DATETIME()),&back.,E))) ;

    %* no semiclolon on next line ;

    %Unquote(%Str(%')%sysfunc(Putn(&set_dttm, datetime20.))%str(%')DT)

%Mend ;

%Put Where extract_dttm Between %Datelimit(-3) and %Datelimit(-1) ;

Where extract_dttm Between '  31JUL2012:23:59:59'DT and '  30SEP2012:23:59:59'DT

Enjoy

Richard in Oz

TurnTheBacon
Fluorite | Level 6

Thanks, turns out I didn't need the %sysevalf for it to run. The log now shows me the value 1667347199 for &extract_dttm. However, I'm still unclear on how I can make the Extract work as intended, to extract all values where &extract_dttm is between Valid_From_DTTM and Valid_To_DTTM.

The where-statement says: &extract_dttm. BETWEEN Valid_From_DTTM AND Valid_From_DTTM.

&extract_dttm currently has the value 1667347199, while Valid_From_DTTM and Valid_To-DTTM have the NLDATM21-format, appearing as for example 02SEP12:12:31:02.

What can I do in the where-statement to turn Valid_From_DTTM and Valid_From_DTTM into the same kind of format as &extract_dttm? I assume that's the way to go.

Sorry for the newbie'ish question. Smiley Happy

TurnTheBacon
Fluorite | Level 6

One of the rows in the input table has these values:

VALID_FROM_DTTM: 02OCT12:12:31:02

VALID_TO_DTTM: 01JAN99:00:00:00


Using RichardinOz's helpful suggestion, the log confirms that &extract_dttm has this value: 31OCT12:23:59:59.


Yet, the following where-statement in the Extract doesn't extract any values:

&extract_dttm BETWEEN VALID_FROM_DTTM AND VALID_TO_DTTM


This is the precode I'm using (which generates the correct value 31OCT12:23:59:59😞

%let extract_dttm = %Sysfunc(putn(%sysfunc(intnx(DTMONTH, %sysfunc(DATETIME()), &back., E)), datetime.));


How can I modify the where-statement or precode to resolve this, so that the Extract works as intended? I've tried using ""dt on the variables in numerous combinations, but perhaps I've missed one.


UPDATE: Sorry, resolved, thanks again Richard. Smiley Happy

Tom
Super User Tom
Super User

You need to use four digit years in your datetime literals.  Depending on the setting of the yearcutoff option '99' could be interpreted as '1999' or '2099'.


data test ;

input (fromdt todt) (:datetime20.);

format fromdt todt datetime20. ;

put (_all_) (=);

cards;

02OCT12:12:31:02 01JAN99:00:00:00

02OCT2012:12:31:02 01JAN2099:00:00:00

run;


fromdt=02OCT2012:12:31:02 todt=01JAN1999:00:00:00

fromdt=02OCT2012:12:31:02 todt=01JAN2099:00:00:00

Datetime variables in SAS are numbers that store the number of seconds since 01JAN1960. So the time 31OCT2012:23:59:59 will be stored as the number 1667347199.  You can specify a specific datetime value by that number or you can use a datetime literal to make it easier for humans to read.

If you have a macro variable with the value 31OCT2012:23:59:59 and you want to use it in a WHERE statement to compare it to values in a datetime variable then just use the datetime literal format.

WHERE "&extract_dttm"dt BETWEEN VALID_FROM_DTTM AND VALID_TO_DTTM


Now if your dataset variables are character strings instead of actual datetime values then you need to convert those to numbers to get the comparison to work. 


WHERE "&extract_dttm"dt BETWEEN input(VALID_FROM_DTTM,datetime.) AND input(VALID_TO_DTTM,datetime.)



sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 1492 views
  • 3 likes
  • 3 in conversation