I am using SAS to bring over a table that sits in a Microsoft SQL Server and and dump it into Hadoop.
The problem I am facing is that the data variable: INSURANCE_DATE.Week_Start_Date is a Datetime 22.3, but needs to be converted into yymmddn8.
I am bringing 3 years of data over, the
entry code piece:
%let three_year_start=%sysfunc(putn(%sysfunc ( intnx(year,%sysfunc(today()), -3)), yymmddn8.)); /* */
%let three_year_end=%sysfunc(putn(%sysfunc(today()), yymmddn8.)); /is today/
works fine, but I am not sure how to format
INSURANCE_DATE.Week_Start_Date properly
so that my where clause works.
%let three_year_start=%sysfunc(putn(%sysfunc (
intnx(year,%sysfunc(today()), -3)), yymmddn8.)); /* */
%let three_year_end=%sysfunc(putn(%sysfunc(today()), yymmddn8.)); /*is
today*/
proc SQL;
create table BA_INS as
SELECT
format (INSURANCE_DATE.Week_Start_Date) yymmdd10.) as Week_Start_Date
FROM
dbo.DIM_INSURANCE_DATE
WHERE
(dbo.DIM_INSURANCE_DATE.Week_Start_Date
between &three_year_start. and &three_year_end.);
quit;
I need a solution as how to convert that datatime 22.3 format into yymmdd10. within the proc sql query
If the source value pulled from SQL Server is, in SAS, presenting itself SAS datetime value, and you want the target value to be pushed to Hadoop from SAS to be as from a SAS date value, you can use the datepart function in SAS.
proc sql;
create table HADOOP.TARGET_TABLE as
select
…
, datepart(Week_Start_Date) as Week_Start_Date format=date9.
…
from
SQLSRV.SOURCE_TABLE
…
;
I don't think the actual date format is important, only that it is one of the SAS date formats. The SAS/Connect engine will examine the SAS column going to target, see the date format and automatically make any tweaks needed to insert the SAS date value as a date value in the target system.
use datepart to take format and then apply format
SELECT
datepart(INSURANCE_DATE.Week_Start_Date) format= yymmdd10. as Week_Start_Date
Not sure what you plan on using the macro variables for, but your are using an extra %SYSFUNC() call. You do not need to call PUTN() to format the value, %SYSFUNC() already will take a format specification.
%let three_year_start=%sysfunc(intnx(year,%sysfunc(today()),-3,b),yymmddn8.);
%let three_year_end=%sysfunc(today(), yymmddn8.);
So this will get you values like 20160101 and 20190123. Note to SAS if you did not enclose those in quotes they would be treated as the numbers 20,160,101 and 20,190,123 rather than anything to do with either date values or datetime values. And if you did enclose them in quotes then they would just be strings.
If you want to just generate a date value then don't bother to format the numbers. Then you will get values like THREE_YEAR_START=20454 and THREE_YEAR_END=21572 which represent the number of days since 1960. Then in your SQL code you could use those. But first you would need to convert your datetime value to a date value. Otherwise you would be comparing apples and oranges (seconds and days).
%let three_year_start=%sysfunc(intnx(year,%sysfunc(today()),-3,b));
%let three_year_end=%sysfunc(today());
...
where datepart(Week_Start_Date) between &three_year_start and &three_year_end
Or you could format your macro variables to look like values that the DATE (or DATETIME) informat could understand and use them as date (or datetime) literals by adding quotes and appropriate suffix letter(s).
DATE Literals
%let three_year_start=%sysfunc(intnx(year,%sysfunc(today()),-3,b),date9.);
%let three_year_end=%sysfunc(today(), date9.);
...
where datepart(Week_Start_Date) between "&three_year_start"d and "&three_year_end"d
DATETIME literals
%let three_year_start=%sysfunc(intnx(dtyear,%sysfunc(datetime()),-3,b),datetime19.);
%let three_year_end=%sysfunc(datetime(), datetime19.);
...
where Week_Start_Date between "&three_year_start"dt and "&three_year_end"dt
Related
I am trying to pull in a date time variable that is formatted as a char 55. I would like to be able to do it within my initial pull so I can limit on the date.
Here is the format for field I am pulling in.
09/28/2017 00:00:00
TYPE: Char
Len: 55
Format: $55
Informat: $55
I have tried so many things to convert it but with no luck. My variable always comes out blank.
Convert character datetime to numeric using the input function then use the datepart function to retrieve only the date part and apply proper formatting after.
proc sql;
create table want as
select datepart(input(date, anydtdtm.)) as date format=MMDDYY10.
from have;
quit;
proc sql;
connect to hadoop(schema=pharm PROPERTIES='tez.queue.name=user_queue');
create table daily as
select datepart(input(date, anydtdtm.)) as date format=MMDDYY10.
from connection to hadoop
(select date from table limit 100)
;
quit;
I am writing a program in Proc SQL. the program takes various input files, where the filenames change from month to month (i.e. myfile_YYYY_MM or mytable_YYYYMM, or mydata_YY_M).
Most of the program is now dynamic, and the user is asked to input reporting date via a prompt when executing the program.
The "Prompt Date" (&Rep_Date.) in the code has format DD MON YYYY (31may2018), and I need to set up one macro variable transforming this value to format YYMMn6 (i.e. 201805).
The syntax looks like this:
%let Period = input("&Rep_Date."d,YYMMN.);
This worked when trying to create a d9 variable, and for creating a month/year variable, like this:
%let date = "&Rep_Date."d; /*Last day execution month*/
%let year = %sysfunc(year("&Rep_Date."d));
%let month = %sysfunc(month("&rep_Date."d));
for some reason, the same does not work when trying to format the date to YYMMn6.
I also tried creating the variable "Period" in a temporary SAS table like this, but again no luck:
Data dates;
Period = input((&Rep_date.,6.), yymmn6.);
format Period yymmn6.;
Run;
Any ideas on where I am going wrong?
I believe the problem is because of the fact that you are using just the input function in your %let statement.. This won't resolve properly. The right thing would be to use the %sysfunc macro function with the input function. The issue is that sysfunc doesn't work with the input function. Hence, the solution is to use %sysfunc(putn()). Here is an example.
Edit:
Not sure what you're trying to achieve but the %window function (assuming you're using Windows) allows you to take input through a prompt and then create a macro variable from the input. Here is an example:
%global Period;
%window info
#5 #5 'Please enter date:'
#5 #40 _Date 9 attr=underline;
%display info;
%put &_Date.;
%macro da(Rep_Date=&_Date);
%let Period = %sysfunc(putn("&Rep_Date."d,YYMMN.));
%put &Period.;
%mend;
%da();
This should work.
What is going wrong ? You are mixing contexts and misconstruing a representation as a literal (literally - pun literally intended).
In short
Have your macro code utilize the date representation value as the basis for a literal value that is used in a putN() invoked by %sysfunc.
%let Rep_Date = 18-JUN-2018; * some date representation;
%let Period = %sysfunc(PUTN("&Rep_Date."D,YYMMN.));
%put NOTE: Period=%superq(Period);
In Long
From the Glossary in "SAS Help and Documentation" (F1)
SAS date valuean integer that represents a date in SAS software. The integer represents the number of days between January 1, 1960, and another specified date. For example, the SAS date value 366 represents the calendar date January 1, 1961.
SAS date constanta string in the form 'ddMMMyy'd or 'ddMMMyyyy'd that represents a date in a SAS statement. The string is enclosed in quotation marks and is followed by the character d (for example, '6JUL01'd, '06JUL01'd, '6 JUL2001'd, or '06JUL2001'd).
date and time formatinstructions that tell SAS how to write numeric values as dates, times, and datetimes.
date and time informatthe instructions that tell SAS how to read numeric values that are represented as dates, times, and datetimes.
Textual values of the form DD MON YYYY is one form of a representation of a date. The form with four year digits can be input using the instructions inherent in the informat DATE11.. The SAS date literals (SAS date constant) are of the form DDMONYYYYD with or without a variety of spaces, dashes, slashes, etc.
Another code variation similar to the 'In short' would input the date text using a specific format (date11.) instead of relying on the system doing a date literal interpretation.
%let Rep_Date_text_representation = 18/JUN/2018;
%let Rep_Date_value = %sysfunc(inputN(&Rep_Date_text_representation,date11.));
%let Period = %sysfunc(putn(&Rep_Date_Value,yymmn.));
%put NOTE: &=Rep_Date_text_representation ;
%put NOTE: &=Rep_Date_value;
%put NOTE: &=Period;
I've a table named cust_field_value_l in sas server under Sasoprsk library having a column name value_dt who store date data.
When I get data from this table it comes in binary data as 1.827E9 or 1.826E9 and gives ***** when i print it in my webout file.
proc sql noprint;
create table date(date datetime);
quit;
proc sql noprint;
insert into date(date)
select value_dt
from Sasoprsk.cust_field_value_l;
quit;
Now my date table has data as 1.826E9 etc.
data _null_;
put "<html><body>";
run;
data _null_;
put numberOfObservations=;
set work.date nobs=numberOfObservations;
file _webout;
put date;
run;
data _null_;
put "</body></html>";
run;
I'm receiving ***** in my webout file
I've tried this too but it only giving me wrong date
proc sql noprint;
insert into date(date)
select (today()-datepart((value_dt / 1000.0)+315601200))
from Sasoprsk.cust_field_value_l;
quit;
this code giving me only 03NOV07 for all the date values.
I don't know how can i get correct date value from db and show them in webout file;
value_dt has all the values in 23NOV2017:00:00:00 formate.
value_dt
23NOV2017:00:00:00
15NOV2017:00:00:00
20NOV2017:00:00:00
without comparing with today()
date
1.827E9
1.826E9
1.827E9
and its giving me ***** for every row
with comparing with today()
date
03NOV07
03NOV07
03NOV07
and printing 03NOV07 for every date data
SAS only has two data types. Fixed length character strings and floating point numbers. DATE values are stored as the number of days since '01JAN1960'd and DATETIME values are stored as the number of seconds since '01JAN1960:00:00'dt. The numbers you are displaying are consistent with a datetime value. The TODAY() function (also know as the DATE() function) will return a DATE value. If you want a DATETIME value use the DATETIME() function instead.
If you want users to supply date values (like '03NOV2007'd) to filter your datetime variable then you will need to convert one or the other before comparing them. Say you have a datetime variable name TIMESTAMP and you want to find events that occured today you could use something like
where today() = datepart(timestamp)
If you are creating a new data set by reading values from an existing dataset then just use a DATA step. No need to pre-creating the dataset and then "inserting" the observations into it. Or to bother with using PROC SQL. Just create the dataset you want.
data date ;
set Sasoprsk.cust_field_value_l ;
keep value_dt ;
rename value_dt=date ;
format value_dt datetime20. ;
run;
But if the whole purpose is just to print the values to the _WEBOUT fileref then there is no need to make a copy of the data first. Just print directly from the source data.
data _null_;
put numberOfObservations=;
set Sasoprsk.cust_field_value_l nobs=numberOfObservations;
file _webout;
put value_dt datetime20.;
run;
If you only want to print the date part of the datetime value then you can use the DTDATE9. format instead.
I need to use a date/timestamp field in my where clause where it is >today()1pm
I'm setting it up to be a scheduled task, so the "today()" part is important
I dont know how to combine that with the time piece though
all I could come up with was this- and it seems like very inefficent code if it even works
datepart(fielda)=today() and timepart(fielda)>01:00:00pm
I need to be able to say here are the items with a timestamp of "today" after "1pm"
*I am passing my sql to an underlying database.
If you're using PROC SQL directly (not pass-through) you can use the SAS dhms function:
proc sql noprint;
* Assume myData contains a var named datestamp;
create table selected as
select * from myData
where datestamp > dhms(today(), 13, 0, 0)
;
quit;
The function constructs a datetime value from the supplied Date, Hour, Minutes and Seconds values, hence dhms.
This won't work if your SQL is being passed through to the underlying database because it's unlikely to understand the dhms function.
this is so much fancier and is easier to use
datefield between to_date(to_char(sysdate-1,'mm/dd/yyyy') || '12:00:00','mm/dd/yyyy hh24:mi:ss') and to_date(to_char(sysdate,'mm/dd/yyyy') || '08:32:27','mm/dd/yyyy hh24:mi:ss')
this will supply all values from yesterday at 12pm through 832am today
Combine a date9-formatted macro variable with the time. This will create a datetime literal. This method is going to be as efficient as can be, since SAS resolves the literal one time only, and can then use any existing index on datestamp.
%let today = %sysfunc(today(), date9.);
proc sql noprint;
create table selected as
select *
from mydata
where datestamp > "&TODAY.:13:00:00"dt
;
quit;
You can confirm the value with the code below.
%put %sysfunc(putn("&TODAY.:13:00:00"dt, mdyampm24.) );
For a SQL92 compliant database engine, the where syntax is as follows:
EXTRACT(HOUR FROM fielda) >= 13
Having some issues deleting rows from a data set. They need to be deleted by a date criteria, but the variable is in e8601dt. format. One thing I noticed about the variable is that its a number type variable, but left aligned (not sure if that has relevance or not), so I attempted to substring, and some additional attempts (below)...no success -
PROC SQL;
DELETE *
FROM DATASETS.BATCH_REPORT
WHERE datepart(BATCH_DATE) > '2015-10-01'
;
QUIT;
PROC SQL;
DELETE *
FROM DATASETS.BATCH_REPORT
WHERE BATCH_DATE > '11oct2015'd
;
QUIT;
Assuming there has to be an easy way to call out a value in this format...or will I need to convert this variable to a more compliable format, then do my processing?
OK...did some research. Apparently (and some one please correct me if I am wrong)...to use the e8601dt. format, a date value needs to be multiplied by 86400, then you can apply the format. So.....dividing by 86400 brought me back to the SAS data as an integer. This did the trick :
PROC SQL;
DELETE *
FROM SETS
WHERE ID >= 20372
;
QUIT;
You're close! Date conversions are a pain between systems. The representation of the values depends on the environment configuration.
Within proc SQL, I think you have to specify oracle functions (not the SAS datepart) Looks like you've figured out that Oracle's 'DATE' datatype stores both date&time within the same value. The DATE datatype stores the year (including the century), the month, the day, the hours, the minutes, and the seconds (after midnight). SAS has 2 different date types: date and datetime.
I'd suggest using the oracle to_date() function to compare against a character date, i.e.
WHERE BATCH_DATE > to_date('2015-10-01','yyyy-mm-dd')
If desired, you could use the oracle to_char(BATCH_DATE,'mm-dd-yyyy') to cast the date variable to a text value and then compare on the text value. But you loose some of the comparison power.
....edited due to new info about ...ew... db2 ..... :-)
I'm way NOT a DB2 guy, but maybe something like this?
First, set the date as in: (the date passed to DB2 needs the double quotes):
CALL SYMPUT('INT_DATE',"'"||PUT(sas_date,YYMMDDD10.)||"'");
Then use in the SQL as in:
PROC SQL ;
WHERE BATCH_DATE >= &INT_DATE
https://communities.sas.com/t5/SAS-Procedures/DB2-Date9-format-To-SAS-Serial-Date/td-p/32436