DateAdd function in pl/sql - plsql

As the title suggested , I am looking for a function in pl /sql which does something similar like the DateAdd function.
I have been looking and I found the add_months function but I would really like one that is a little more variable since I need to be able to add minutes, hours , days etc.

It appears there's not many solutions :
PL/SQL allows you to perform arithmetic operations directly on date variables. You may add numbers to a date or subtract numbers from a date. To move a date one day in the future, simply add 1 to the date as shown below:
hire_date + 1
You can even add a fractional value to a date. For example, adding 1/24 to a date adds an hour to the time component of that value. Adding 1/(24*60) adds a single minute to the time component, and so on.

Besides adding numbers to dates - though it's the simplest way - you can add intervals like that:
date1 := date2 + interval '1' day;
date1 := date2 + interval '2' month;
date1 := date2 + interval '3' year;
It's almost the same but I prefer latter for better readability.

Related

How to provide the dynamic date value in interval range between clause in analytic function

we provide the following
range between interval '1' day preceding and current row.
Can we provide any date range instead of '1' day?
Yes, but with an interval literal the '1' part can't be a variable; but you can multiply that by some variable:
range between some_number * interval '1' day preceding and current row
You can also use the numtodsinterval() function:
range between numtodsinterval(some_number, 'DAY') preceding and current row
or if you aren't dealing with just a single unit (i.e. a number of days) you can use the to_dsinterval() function:
range between to_dsinterval(some_string) preceding and current row
db<>fiddle
The first options can use any unit, of course; you can have multiple of 12 hours, or 3 seconds, or whatever you want.
The last option allows two formats, so you can pass in an ISO-format duration like 'P5D' or 'P1D12H' or 'P6D12H13M14.567S' etc., or an 'SQL format' as `6 12:13:14.567'.

Apache Drill: Group by week

I tried to group my daily data by week (given a reference date) to generate a smaller panel data set.
I used postgres before and there it was quite easy:
CREATE TABLE videos_weekly AS SELECT channel_id,
CEIL(DATE_PART('day', observation_date - '2016-02-10')/7) AS week
FROM videos GROUP BY channel_id, week;
But it seems like it is not possible to subtract a timestamp with a date string in Drill. I found the AGE function, which returns an interval between two dates, but how to convert this into an integer (number of days or weeks)?
DATE_SUB may help you here. Following is an example:
SELECT extract(day from date_sub('2016-11-13', cast('2015-01-01' as timestamp)))/7 FROM (VALUES(1));
This will return number of weeks between 2015-01-01 and 2016-11-13.
Click here for documentation

How do you update an existing date to a random date in a range?

In one of my tables I have datetime field in which the data in the table column is populated with something like "2016-01-07 01:33:00".
What I want to do is change ONLY the date to a random date within a range (ie: 2016-02-01 thru 2016-02-28) without changing the time. The end result might be "2016-02-13 01:33:00".
What mysql command string would accomplish this task?
Something like
UPDATE someTable SET someDate = DATE_ADD(
someDate,
INTERVAL
DATEDIFF(rangeStart, someDate) +
ROUND(RAND()*DATEDIFF(rangeEnd, rangeStart))
DAY
);
where someTable.someDate is your existing data, and rangeStart and rangeEnd are the boundaries of your target date range.
Here you take the initial date, add enough days to it to reach the range start, and then further add a random number of days no greater than the number of days in your target range.
In MsSQL it could be:
select dateadd(day,cast((RAND() * 30) as int),getdate())
Substitute getdate() with your input date.
(RAND() * 30) is used to randomly generate a number of days up to 30.

How to add/subtract date/time components using a calculated interval?

I'd like to get this to work in Teradata:
Updated SQL for better example
select
case
when
current_date between
cast('03-10-2013' as date format 'mm-dd-yyyy') and
cast('11-03-2013' as date format 'mm-dd-yyyy')
then 4
else 5
end Offset,
(current_timestamp + interval Offset hour) GMT
However, I get an error of Expected something like a string or a Unicode character blah blah. It seems that you have to hardcode the interval like this:
select current_timestamp + interval '4' day
Yes, I know I hardcoded it in my first example, but that was only to demonstrate a calculated result.
If you must know, I am having to convert all dates and times in a few tables to GMT, but I have to account for daylight savings time. I am in Eastern, so I need to add 4 hours if the date is within the DST timeframe and add 5 hours otherwise.
I know I can just create separate update statements for each period and just change the value from a 4 to a 5 accordingly, but I want my query to be dynamic and smart.
Here's the solution:
select
case
when
current_date between
cast('03-10-2013' as date format 'mm-dd-yyyy') and
cast('11-03-2013' as date format 'mm-dd-yyyy')
then 4
else 5
end Offset,
(current_timestamp + cast(Offset as interval hour)) GMT
You have to actually cast the case statement's return value as an interval. I didn't even know interval types existed in Teradata. Thanks to this page for helping me along:
http://www.teradataforum.com/l081007a.htm
If I understand correctly, you want to multiply the interval by some number. Believe it or not, that's literally all you need to do:
select current_timestamp as right_now
, right_now + (interval '1' day) as same_time_tomorrow
, right_now + (2 * (interval '1' day)) as same_time_next_day
Intervals have always challenged me for some reason; I don't use them very often. But I've had this little example in my Teradata "cheat sheet" for quite a while.
Two remarks:
You could return an INTERVAL instead of an INT
The recommended way to write a date literal in Teradata is DATE 'YYYY-MM-DD' instead of CAST/FORMAT
select
case
when current_date between DATE '2013-03-10' and DATE '2013-11-03'
then interval '4' hour
else interval '5'hour
end AS Offset,
current_timestamp + Offset AS GMT

Subtract 1 year from datetime

I have seen a lot of info on how to subtract one datetime from the other and how to add years on to a datetime. but the following is giving me a headache....
When a user inserts a record a hidden field called subdate with a value of datetime.now is added to the db.
I then need to have an 'old records' page that lists all the entries that are over 1 year old and was hoping to use something (but using subtract method) similar to;
(DateTime.Now.AddYears(1))
but there is no SubtractYears available? Why?
Please can you let me know how I achieve the same result?
DateTime.Now.AddYears(-1)
From the documentation:
A number of years. The value parameter can be negative or positive.
now = datetime.now()
last_year = (now.year - 1)
datestr = (datetime.strptime(str(now.year - 1), "%Y")).strftime("%y")
print(f"Last Year: {datestr}")
The output will be:
Last Year: 20
If you prefer to have four digit year then change %y to %Y

Resources