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

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.

Related

SAS EG DATE/TIME IN WHERE CLAUSE

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

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

Strange behaviour of Sql query with between operator

There is this strange error in sql query.
The query is something like this.
select * from student where dob between '20150820' and '20150828'
But in the database the column of dob is varchar(14) and is in yyyyMMddhhmmss format,Say my data in the row is (20150827142545).If i fire the above query it should not retrive any rows as i have mentioned yyyyMMdd format in the query.But it retrives the row with yesterday date (i.e 20150827112535) and it cannot get the records with today's date (i.e 20150828144532)
Why is this happening??
Thanks for the help in advance
You can try like this:
select * from student
where convert(date,LEFT(dob,8)) between
convert(date'20150820') and convert(date,'20150828'))
Also as others have commented you need to store your date as Date instead of varchar to avoid such problems in future.
As already mentioned you would need to use the correct date type to have between behave properly.
select *
from student
where convert(date,LEFT(dob,8)) between '20150820' and '20150828'
Sidenote: You don't have to explicitly convert your two dates from text as this will be done implicitly as long as you use an unambiguous date representation, i.e. the ISO standard 'YYYYMMDD' or 'YYYY-MM-DD'. Of course if you're holding the values in variables then use date | datetime datatype
declare #startdate date
declare #enddate date
select *
from student
where convert(date,LEFT(dob,8)) between #startdate and #enddate
Sidenote 2: Performing the functions on your table dob column would prevent any indexes on that column from being used to their full potential in your execution plan and may result in slower execution, if you can, define the correct data type for the table dob column or use a persistent computed column or materialised view if your performance is a real issue.
Sidenote 3: If you need to maintain the time portion in your data i.e. date and time of birth, use the following to ensure all records are captured;
select *
from student
where
convert(date,LEFT(dob,8)) >= '20150820'
and convert(date,LEFT(dob,8)) < dateadd(d,1,'20150828')
All you have to do is to convert first the string to date.
select *
from student
where dob between convert(date, '20150820') and convert(date, '20150828')
Why is this happening?
The comparison is executed from left to right and the order of characters is determined by the codepage in use.
Sort Order
Sort order specifies the way that data values are sorted, affecting
the results of data comparison. The sorting of data is accomplished
through collations, and it can be optimized using indexes.
https://msdn.microsoft.com/en-us/library/ms143726.aspx
There are problems with between in T-SQL.
But if you want a fast answer convert to date first and use >= <= or even datediff to compare - maybe write a between function yourself if you want the easy use like between and no care about begin and start times ...
What do BETWEEN and the devil have in common?

Issue with Fetching Date using SYSDATE?

I have a table structure having a EMP_DATE column as below
ID EMP_DATE
---- -----------
5400 14-FEB-2012
and i have inserted records into the table as below
INSERT INTO TEST_DATE VALUES(5400,SYSDATE);
After inserting records while i am trying to fetch the records of those who has EMP_DATE
as SYSDATE its giving no rows selected.
For time being let the SYSDATE be '01-JUL-2012`
SELECT * FROM TEST_DATE WHERE EMP_DATE = SYSDATE;
(OR)
SELECT * FROM TESt_DATE WHERE EMP_DATE = '01-JUL-2012';
i was not able figure out any solution .
Any suggestions would be helpful .
The main problem is that a date includes hours, minutes and seconds, which you're not allowing for. If you want everything for a single day you can use the trunc function in order to get this:
SELECT * FROM TEST_DATE WHERE trunc(EMP_DATE) = trunc(SYSDATE);
By default trunc removes the time portion of a date, when operating on a date column. I would normally recommend a functional index on trunc(emp_date) in order to optimize this query. Something like:
create index i_test_date on test_date(trunc(emp_date));
I've built a little SQL Fiddle to demonstrate this.
There is an additional problem; though Oracle does support ANSI date literals your second query is wrong. Always, explicitly convert to a string to a date using the to_date function.
SELECT * FROM TEST_DATE WHERE EMP_DATE = to_date('01-07-2012','dd-mm-yyyy');
I've used the mm datetime format model instead of mon as there's no guarantee that JUL will always mean July; it depends on your NLS parameters, what "date language" your particular database or session is using. A datetime format model is how you tell the database the format of whatever string you're passing it to be converted into a date.
If you're interested the ANSI syntax for your second query would be:
SELECT * FROM TESt_DATE WHERE trunc(EMP_DATE) = DATE '2012-07-01'
It must be in this format (YYYY-MM-DD) to work.

Oracle query not displaying date properly

In Oracle, there is a column(dateColumn) in a table with column type = DATE and the value for a particular record is showing as '10/03/2010' when I do a select * from table.
Now, when I do:
SELECT *
FROM table
WHERE dateColumn < '01-JAN-11'
Nothing shows up. When I do:
SELECT *
FROM table
WHERE dateColumn > '01-JAN-11'
The record shows up.
Why is this behaving this way? "10/03/2010" is 10th MArch 2010 so clearly that is < 01 Jan 2011.
There is no definitive date format -- it can be different by region or even business. That's the reality without even considering SQL...
In Oracle, the means of evaluating a string as a date requires you to use the TO_DATE function:
SELECT *
FROM table
WHERE dateColumn > TO_DATE('01-JAN-11', 'DD-MON-YY')
You need to supply the format mask to instruct Oracle how to interpret the date you're supplying it.
The function is often different on other databases, but the experience is otherwise the same. Most databases accept 'YYYY-MM-DD' for implicit conversion of a string into a date. Explicit conversion is when you use a function, like TO_DATE to explicitly change the data type.
Try to use to_date:
select * from table where dateColumn < to_date('01-JAN-11', 'dd-MON-YY')