oracle sql code to sas proc sql - add months - sql

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.)

Related

Converting a character date to SAS Date in PROC SQL

I am trying to convert a character to a date in sas and its driving me nuts that it is not working. The date is currently in character format as below
200609
I want to convert it to a similar date structure in proc sql but just cant get it to work. I am using the following code:
input(date,anydtdtm.) as Perf_Date format = date9.,
Can anyone suggest where I am going wrong?
Use the actual informat. You're using anydtDTM - DTM means date time. You could also try ANYDTDTE which is looking for a date.
YYMMN6. works though and you can be sure it's correct.
data want;
x='200609';
y=input(catt(x, '01'), yymmn6.);
format y date9.;
run;
proc print;run;
01SEP2006

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

SAS SQL Datepart function returning odd values

I'm having a massive problem with a project that I just can't seem to get right. I'm trying to modify my data variable as its currently in a datetime format. The first data is 30Mar12:00:00:00. I've been advised to use the code below but it returns a value like 30mar60:5:30:00. I just want the date component and have no idea how the data even got exported in this format as it wasn't like this in Microsoft Access. I've tried several mods to this code but again just comes up completely blank or sends an error message.
proc sql; update dataset set date = DATEPART(date); quit;
Any advice would be greatly appreciated.
I'm guessing the variable date is numeric and formatted as DATETIME. Once you've carried out the conversion, just change the format to something like DATE9. A SAS datetime value is the number of seconds since 01 Jan 1960, whereas dates are the number of days since 01 Jan 1960. Both are stored as numbers, so using the correct format to display the value is key. Example below.
data _null_;
a='30Mar12:00:00:00'dt;
b=datepart(a);
c=b;
format a b datetime. c date9.;
put a b c;
run;

Comparing dates in SQL returns wrong records

I am trying to locate a date in database between two specific dates entered by user. Something like:
SELECT date FROM table WHERE date>=dateFrom AND date<=dateTO
I have the following table:
I have made a mistake saving the date as VARCHAR and now i have to do all the str_to_date and date_format as i am using phpMyAdmin. I somehow did it but i am facing this strange problem using this query:
SELECT date_format(str_to_date(data,'%d/%m/%Y'),'%d/%m/%Y') AS data FROM montaggio WHERE data>=date_format(str_to_date('29/08/2014','%d/%m/%Y'),'%d/%m/%Y')
The query would return to me only the date 19/08/2014 where as i expected it to return 01/09/2014. On the other hand if it enter the query
SELECT date_format(str_to_date(data,'%d/%m/%Y'),'%d/%m/%Y') AS data FROM montaggio WHERE data>=date_format(str_to_date('29/08/2014','%d/%m/%Y'),'%d/%m/%Y') AND data<=date_format(str_to_date('05/09/2014','%d/%m/%Y'),'%d/%m/%Y')
The query returns nothing.
I am using phpMyAdmin.
What am i missing here? Any help would be appreciated!
You do seem a bit confused. All the operations on dates should be done on the date data type. There is no need to convert things back to strings:
SELECT data
FROM montaggio
WHERE str_to_date(data, '%d/%m/%Y') >= str_to_date('29/08/2014', '%d/%m/%Y')
You seem to understand the real solution, which is to store dates/times in the database using the correct type. If you have to use strings for dates, then always stored them as YYYY-MM-DD, so comparisons and sorting will work correctly.

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.