sql coding to_date meaning - sql

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.

Related

use of trunc date in sql

can anyone explain me the working of trunc(date) function in oracle.
my query is as below.
select trunc(tran_date) from tablename;
i have not passed any format type.
If i compare the date present in table without having trunc(date) it will not give any output.
and if compare date table with trunc(date) it will give me proper ouptut.
please explain how it is working.
and is there any replacement for trunc function as it is taking too much time.
trunc(tran_date) returns the date portion of the date column with no time component (which is midnight at the start of the day).
Despite its name, the date data type in Oracle includes the time. This is even more confusing because you sometimes do not see the time in the result set (depending on how you access the data).
The dates that you are comparing to have no time component. So, the comparison works with trunc(). But the time component on tran_date prevents the comparison from working without trunc().

oracle sql code to sas proc sql - add months

I am rewriting code from oracle sql to sas proc sql and I have problem with this:
where demandes_fin.per_idt = to_char(add_months(to_date(fin.per_idt,'yyyymm'),1),'yyyymm'))
demandes_fin.per_idt and fin.per_idt are INT variables - for example 201612.
functions to_char, add_months, to_date are not working in SAS proc sql. I have tried to replace them using put, input, intnx, format but it didn't work as I expected.
I have tried to put this code in select statement to see values, that was generated:
intnx('month', input(put(fin.per_idt,6.),yymmn6.), 1) as dt1
fin.per_idt was 201701 and generated value was 20851.
Do you have any ideas how to code it?
Thank you so much.
Looks like you have already solved your problem. SAS stores dates as the number of days since 01JAN1960. The number 20,851 represents 01FEB2017 which is one month after January 2017.
If you want to keep your result as a SAS date value just add the FORMAT keyword to your definition so that the date will display in a format that humans can understand.
intnx('month', input(put(fin.per_idt,6.),yymmn6.), 1) as dt1 format date9.
If you want to convert it back into the strange integer value you started with then just add some more PUT() and INPUT() function calls.
input(put(intnx('month', input(put(fin.per_idt,6.),yymmn6.), 1),yymmn6.),6.)

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

Fetching the records which are having all time stamp columns

I am trying to fetch the records which are having all time stamp columns.
I am using the following query to fetch the products that are created between the final date and (final date - 30) days, i.e products created during the last 30 days that fall in the 'final date' range.
I have products that are created on 30-OCT-2014. For the same products, the initiated date is 12-NOV-2014. However they are not being fetched when I using the below query.
SELECT A.ROW_ID,
A.PROD_NAME
FROM PROD A,
PROD_REL B
WHERE A.ROW_ID = B.PAR_ROW_ID
AND TO_DATE(A.CREATED_DT,'YYYY-MM-DD') BETWEEN (TO_DATE(B.FINAL_DATE,'YYYY-MM-DD') - 30)
AND (TO_DATE(B.FINAL_DATE,'YYYY-MM-DD'));
So, could you please let me know if I am missing something?
Here is a link to a SQLFiddle that demonstrates the problem.
… or just fix your format string TO_DATE(A.CREATED,'DD-MON-YYYY')
SQL Fiddle
Storing dates as DATE, is , of course, always a good starting point.
Since your data types are all dates, there is no need to use to_date. It's harmful, in fact, since to_date doesn't take a date as a parameter. Oracle has to do an implicit conversion from a date to a string, using your session's NLS_DATE_FORMAT which gets passed in to to_date and converted back to a date using the explicit format mask you specified. If the two conversions aren't using the same format mask, bad things happen.
Your WHERE clause just needs to be
AND a.created_dt BETWEEN b.final_date - 30
AND b.final_date
If I make that change, your SQLFiddle returns two rows

Date range comparison using varchar columns in Teradata

I've been tasked to take a calendar date range value from a form front-end and use it to, among other things, feed a query in a Teradata table that does not have a datetime column. Instead the date is aggregated from two varchar columns: one for year (CY = current year, LY = last year, LY-1, etc), and one for the date with format MonDD (like Jan13, Dec08, etc).
I'm using Coldfusion for the form and result page, so I have the ability to dynamically create the query, but I can't think of a good way to do it for all possible cases. Any ideas? Even year differences aside, I can't think of anything outside of a direct comparison on each day in the range with a potential ton of separate OR statements in the query. I'm light on SQL knowledge - maybe there's a better way to script it in the SQL itself using some sort of conversion on the two varchar columns to form an actual date range where date comparisons could then be made?
Here is some SQL that will take the VARCHAR date value and perform some basic manipulations on it to get you started:
SELECT CAST(CAST('Jan18'||TRIM(EXTRACT(YEAR FROM CURRENT_DATE)) AS CHAR(9)) AS DATE FORMAT 'MMMDDYYYY') AS BaseDate_
, CASE WHEN Col1 = 'CY'
THEN BaseDate_
WHEN Col1 = 'LY'
THEN ADD_MONTHS(BaseDate_, -12)
WHEN Col1 = 'LY-1'
THEN ADD_MONTHS(BaseDate_, -24)
ELSE BaseDate_
END AS DateModified_
FROM {MyDB}.{MyTable};
The EXTRACT() function allows you to take apart a DATE, TIME, or TIMESTAMP value.
You have you use TRIM() around the EXTRACT to get rid of the whitespace that is added converting the DATEPART to a CHAR data type. Teradata is funny with dates and often requires a double CAST() to get things sorted out.
The CASE statement simply takes the encoded values you suggested will be used and uses the ADD_MONTHS() function to manipulate the date. Dates are INTEGER in Teradata so you can also add INTEGER values to them to move the date by a whole day. Unlike Oracle, you can't add fractional values to manipulate the TIME portion of a TIMESTAMP. DATE != TIMESTAMP in Teradata.
Rob gave you an sql approach. Alternatively you can use ColdFusion to generate values for the columns you have. Something like this might work.
sampleDate = CreateDate(2010,4,12); // this simulates user input
if (year(sampleDate) is year(now())
col1Value = 'CY';
else if (year(now()) - year(sampleDate) is 1)
col1Value = 'LY'
else
col1Value = 'LY-' & DateDiff("yyyy", sampleDate, now());
col2Value = DateFormat(sampleDate, 'mmmdd');
Then you send col1Value and col2Value to your query as parameters.