SAS EG DATE/TIME IN WHERE CLAUSE - sql

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

Related

SAS Datetime 22.3 to yymmddn8

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

PROC SQL: Delete rows by Date with format of e8601dt

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

PLSQL - Add days to date in format dd/mm/yyy +1

I want to write a PLSQL query in the following way:
Select ...
FROM ...
WHERE
Date = '06/FEB/2011' + 7(days)
Im new to PLSQL, I've seen solutions such as date+1, but that requires by date to be inside a variable.
I tired putting into a variable like the following:
declare date1 date;
begin
date1 := '06/FEB/2015';
select *
from
...
where
DATE_LABEL = date1 + 1;
end;
But it keeps giving me an error that is expecting an INTO statement in the SELECT. Im not sure what this means.
Thanks
The DATE data type is not stored as a string, so hard-coding to a specific format is not advised, as the format may change based on your database/session NLS_DATE_FORMAT value. A more portable expression is to include the data format mask in the query, such as:
select *
from table Foo
where date_col = to_date('06/FEB/2011','DD/MON/YYYY) + 7;
The date format masks values are documented here.
When executing a query within a pl/sql block, you have have to define somewhere for the result set to be stored upon return. You need to use a cursor for that. In your example, if you only have one row to return, you can declare a placeholder for the result as you did, but need to use the INTO keyword in you select:
declare date1 date;
begin
date1 := '06/FEB/2015';
select date_col
into date1
from table -- etc.
end;
I would suggest to read some PL/SQL tutorials, which cover these basic concepts in detail.
Actually, an even more portable solution is to use the standard Ansi date literal. This will be recognized by a large number of DBMSs. So your code would look like this:
Select ...
FROM ...
WHERE DateField = date '2011-02-06' + 7;
or
WHERE DateField = (date '2011-02-06') + 7;
just to make it clearer.
The date literal must be in the form 'yyyy-mm-dd' and is not affected by system date format settings.
ADDDATE(date, INTERVALE INTEGER DAY)
You should write the number of days also you can use Month, Minute, Hour.

Sql Query using 'Like' is giving results but using '=' does not returns any result in Oracle

The Query using LIKE :(This query when fired gives the desired result)
select * from catissue_audit_event where event_timestamp like '16-DEC-14'
But when using query with '=' results in an empty resultset
select * from catissue_audit_event where event_timestamp='16-DEC-14'
Here event_timestamp is of type Date
Strange thing is that the query runs for other dates such as:
select * from catissue_audit_event where event_timestamp='15-DEC-14'
What can be the issue? I already checked for leading and trailing spaces in the data
Output after running the first query:
In Oracle a DATE (and of course a TIMESTAMP) column contains a time part as well.
Just because your SQL client is hiding the time, doesn't mean it isn't there.
If you want all rows from a specific day (ignoring the time) you need to use trunc()
select *
from catissue_audit_event
where trunc(event_timestamp) = DATE '2014-12-16';
Be aware that this query will not use an index on the event_timestamp column.
You should also not rely on implicit data type conversion as you do with the expression event_timestamp = '16-DEC-14. That statement is going to fail if I run it from my computer because of different NLS settings. Always use a proper DATE literal (as I have done in my statement). If you don't like the unambiguous ISO date, then use to_date():
where trunc(event_timestamp) = to_date('16-12-2014', 'dd-mm-yyyy');
You should avoid using month names unless you know that all environments (which includes computers and SQL clients) where your SQL statement is executed are using the same NLS settings. If you are sure, you can use e.g. to_date('16-DEC-14', 'dd-mon-yy')
The reason why this is different is different to the solution to your issue.
The solution to your issue is to stop performing date comparisons by implicit conversion to a string. Convert your string to a date to perform a date comparison:
select * from catissue_audit_event where event_timestamp = date '2014-12-16'
I cannot stress this enough; when performing a date comparison only compare dates.
Your column EVENT_TIMESTAMP is being implicitly (this is bad) converted to a date in accordance with your NLS_DATE_FORMAT, which you can find as follows:
select * from nls_session_parameters
This governs how date-data is displayed and implicitly converted. The reason why LIKE works and and = doesn't is because your NLS_DATE_FORMAT is masking additional data. In other words, your date has a time component.
If you run the following and then re-select the data from your table you'll see the additional time component
alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss'
Thus, if you want all the data for a specific date without constraint on time you'll need to remove the time component:
select * from catissue_audit_event where trunc(event_timestamp) = date '2014-12-16'
have you tried matching the event_timestamp format example: DD-MMM-YY with the date that you are passing?

sql coding to_date meaning

I have a sql code and couldn't understand the meaning
proc sql; create table tito as
select distinct j.perjobs_pidm,
, to_date(to_char(t.pertito_time_entry_date,'YYYYMMDD') ||t.pertito_time_in,'YYYYMMDDHH24MI') tmi
from stg.pertito t
, stg.perjobs j
where t.pertito_jobs_seqno = j.perjobs_seqno
;quit;
the part I didn't understand is to_date part. How can I change this to SAS language. What is that code means? Thanks!
This is the SQL equivalent of input(put(var,DATE9.)||':'||put(var2,TIME8.),DATETIME.), one way to combine date and time into datetime. A superior SAS method would be
dtvar = dhms(datevar,0,0,timevar);
which uses the date for 'days' and the time for 'seconds' in the DHMS (days hours minutes seconds) function.
This works because a time variable is the number of seconds since midnight; so DHMS(date,0,0,time) creates a datetime variable. IE, if it is 8am sharp, you could either do:
dhms(date,8,0,0) -> 8:00am on date
or
dhms(date,0,0,480) -> 8:00am on date
since 480 = 60*8.
That code is taking two columns pertito_time_entry_date and pertito_time_in, and formatting then concatenating them in the code:
to_char(t.pertito_time_entry_date,'YYYYMMDD') ||t.pertito_time_in
That whole block is then wrapped in to_date() which formats the entire expression to YYYYMMDDHH24MI. This will then be stored as a date value that SAS can understand in the column tito.tmi.