Get systime at a specific time and date - Oracle SQL - sql

Is it possible to do something like this?
SELECT
TO_CHAR(SYSDATE-1, 'MM-DD-YYYY 08:00:00') "Yesterday",
I'd like to get the sysdate from yesterday at 8am

You would write this as:
trunc(sysdate - 1) + interval '8' hour
Or:
trunc(sysdate) - interval '16' hour
Or you can do date arithmetics with integer values rather than intervals:
trunc(sysdate) - 16/24

Truncate the sysdate. That will remove the time portion of the date.
Then add 8/24 (8 hours of the 24), 8/24 equals to 1/3 - 8 hours is a third of a day.
Then display this date value in the format DD-MON-YYYY HH24:MI:SS.
This all adds up to:
SELECT TO_CHAR(TRUNC(SYSDATE) - 1 + 1/3,'DD-MON-YYYY HH24:MI:SS') FROM DUAL;

Related

Oracle SQL Developer showing last 90 days of data

im trying to get a query working that will show the last 90 days of data. this is my timestamp code(it was a unix timestamp) :
"" to_date('1970-01-01','YYYY-MM-DD') +
numtodsinterval(c.f_crtm,'SECOND')- 6/24 as "oracle date" ""
this is the format of my date when the above code is run: 21-JUN-2020 15:48:59
i know it has something to do with the SYSDATE -90 but i cant figure it out.
any help would be great.
I am thinking of something like this:
(date '1970-01-01' + c.f_crtm * interval '1' second) - interval '6' hour > sysdate - interval '90' day
Or to use an index on (f_crtm), you can rearrange the logic:
c.f_crtm > (trunc(sysdate - interval '90' day + interval '6 hour') - date '1970-01-01')*24*60*60

Casting a specific hour and minute and getting the time difference

I have the following:
trunc(sysdate - to_timestamp(trunc(sysdate, 'YYYY-MM-DD') || ' 12:30', 'YYYY-MM-DD HH245:MI') * 1440,1)
What I'm trying to do is, using the date portion of sysdate and casting 12:30 to the time part. Then calculating the difference between sysdate#12:30 and the current sysdate.
I'm getting:
ORA-00932: inconsistent datatypes: expected NUMBER got TIMESTAMP
after the minus sign.
Any ideas?
You're getting that error because you're trying to multiply a timestamp by 1440, rather than the difference between the date and timestamp - multiplication has higher precedence than subtraction. You also have HH245 instead of HH24 in your format model; trunc(sysdate, 'YYYY-MM-DD') will throw "ORA-01898: too many precision specifiers"; and if you changed that to to_char(sysdate, 'YYYY-MM-DD') || ... you would be subtracting a timestamp from a date which gives you an interval, not a number, and would throw a different ORA-00932 error.
Fixing all of those issues, you would end up with:
trunc((sysdate - to_date(to_char(sysdate, 'YYYY-MM-DD') || ' 12:30', 'YYYY-MM-DD HH24:MI')) * 1440, 1)
which would evaluate to 354.2 for me at the moment.
You don't need to convert to or from string though. You can get 12:30 today with:
trunc(sysdate) + (12.5/24)
where trunc(sysdate) gives you midnight today, and 12.5/24 gives you the fraction of a day for 12.5 hours. You can then subtract that from the current time:
sysdate - (trunc(sysdate) + (12.5/24))
to get the difference in days, then multiple that result by 1440 for the number of minutes, and truncate to a single decimal place.
Quick demo with current date and 12:30 today plus the difference three ways:
select sysdate,
trunc(sysdate) + (12.5/24) as "12:30",
sysdate - (trunc(sysdate) + (12.5/24)) as diff_days,
(sysdate - (trunc(sysdate) + (12.5/24))) * 1440 as diff_mins,
trunc((sysdate - (trunc(sysdate) + (12.5/24))) * 1440, 1) as result
from dual;
SYSDATE 12:30 DIFF_DAYS DIFF_MINS RESULT
------------------- ------------------- ---------- ---------- ----------
2019-08-14 18:24:16 2019-08-14 12:30:00 .246018519 354.266667 354.2
As #GordonLinoff hinted, the today-at-12:30 part could be achieved with an interval instead of a fractional day, e.g.:
trunc(sysdate) + 12.5 * interval '1' hour
or more simply and explicitly:
trunc(sysdate) + interval '12:30' hour to minute
You seem to want your final result as the number of minutes, but you could also get it as an interval, either by converting the current number-of-days intermediate result (or number of minutes) with numtodsinterval():
numtodsinterval(sysdate - (trunc(sysdate) + interval '12:30' hour to minute), 'DAY')
which is a bit convoluted, or directly:
select systimestamp,
systimestamp - trunc(sysdate) - interval '12:30' hour to minute as result
from dual;
SYSTIMESTAMP RESULT
------------------------------------ -------------------
2019-08-14 18:24:16.830116000 +01:00 +00 05:54:16.830116
db<>fiddle

Last date with time of the month

Need your help to conclude the query to fetch last date time of the sysdate month.
select to_char(last_day(sysdate),'DD-Mon-YYYY HH24:MI:SS') from dual
it gives last date as expected, but I need time as 23:59:00 which is not possible thru above query.
You could use TRUNC on next day i.e. SYSDATE + 1, and then subtract 60 seconds i.e. 60/86400 to get the desired output.
SQL> SELECT to_char((trunc(last_day(sysdate)) +1) - 60/86400,'DD-Mon-YYYY HH24:MI:SS') dt
2 FROM dual;
DT
--------------------
29-Feb-2016 23:59:00
SQL>
You could also use interval '1' minute or interval '60' second instead of 60/86400.
If you just want it for display for some reason you can hard-code the time into the format mask:
select to_char(last_day(sysdate), 'DD-Mon-YYYY "23:59:00"') from dual;
But you probably really want it as a date object, in which case you can add 23 hours and 59 minutes to the truncated (midnight) date, wchi is 1439 of the 1440 minutes in a day:
select to_char(trunc(last_day(sysdate)) + 1439/1440, 'DD-Mon-YYYY HH24:MI:SS')
from dual;
Or you can go to the next day and remove a minute, either with fractional days or with intervals:
select to_char(trunc(last_day(sysdate)) + interval '1' day - interval '1' minute,
'DD-Mon-YYYY HH24:MI:SS') from dual;
Generally if you're working with time periods you want to include up to 23:59:59, which you can also do with any of those methods, but as Damien_The_Unbeliever said in a comment, it's easier to compare against the start of the next period (e.g. < add_months(trunc(sysdate, 'MM'), 1). It's easy to accidentally miss part of a day by not taking the time into account properly, particularly if you actually have a timestamp rather than a date.

How to subtract hours from a date in Oracle so it affects the day also

I'm trying to subtract date from Oracle so it even effect the day as well. For example, if
the timestamp is 01/June/2015 00 hours and if I subtract 2 hours, I want to be able to go to to 31/May/2014 22 hours.
I tried
to_char(sysdate-(2/11), 'MM-DD-YYYY HH24')
but it only subtracts the hour; it does not touch the day itself.
Others have commented on the (incorrect) use of 2/11 to specify the desired interval.
I personally however prefer writing things like that using ANSI interval literals which makes reading the query much easier:
sysdate - interval '2' hour
It also has the advantage of being portable, many DBMS support this. Plus I don't have to fire up a calculator to find out how many hours the expression means - I'm pretty bad with mental arithmetics ;)
Try this:
SELECT to_char(sysdate - (2 / 24), 'MM-DD-YYYY HH24') FROM DUAL
To test it using a new date instance:
SELECT to_char(TO_DATE('11/06/2015 00:00','dd/mm/yyyy HH24:MI') - (2 / 24), 'MM-DD-YYYY HH24:MI') FROM DUAL
Output is: 06-10-2015 22:00, which is the previous day.
sysdate-(2/11)
A day consists of 24 hours. So, to subtract 2 hours from a day you need to divide it by 24:
DATE_value - 2/24
Using interval for the same:
DATE_value - interval '2' hour
date - n will subtract n days form given date. In order to subtract hrs you need to convert it into day buy dividing it with 24. In your case it should be to_char(sysdate - (2 + 2/24), 'MM-DD-YYYY HH24'). This will subract 2 days and 2 hrs from sysdate.
you should divide hours by 24 not 11
like this:
select to_char(sysdate - 2/24, 'dd-mon-yyyy HH24') from dual

SYSDATE but specify the time

I want to say the follow but substitute the date with SYSDATE but the time between is what I want to adjust. What would the syntax be?
where mydatefield between SYSDATE+'0001' and SYSDATE+'2359'
...
WHERE TO_CHAR( MOPACTIVITY.MOPNOTIFICATIONSENDAT , 'yyyy-mm-dd hh24:mi' )
BETWEEN '2013-07-26 00:00:01' AND '2013-07-26 23:59:59'
;
SYSDATE (or any other date column) in Oracle has the time component. So you need to strip that off and then add the hours/minutes/time condition.
Eg. to say current day 10:00 AM to 3:00 PM, you can say
date_column between (trunc(sysdate) + 10/24) and (trunc(sysdate) + 15/24)
Oracle date arithmetic works on the day level. so, +1 will give you the next day, 1/24 will give you an hour and 10/24 will give you 10:00 AM in the current day.
SQL> alter session set nls_date_format = 'DD-Mon-YYYY HH:MI:SS AM';
Session altered.
1 select sysdate,
2 trunc(sysdate),
3 trunc(sysdate) + 10/24,
4 trunc(sysdate) + 15/24
5* from dual
SQL> /
SYSDATE 26-Jul-2013 06:26:07 PM
TRUNC(SYSDATE) 26-Jul-2013 12:00:00 AM
TRUNC(SYSDATE)+10/24 26-Jul-2013 10:00:00 AM
TRUNC(SYSDATE)+15/24 26-Jul-2013 03:00:00 PM
For your question, you seem to be interested between current day and next day, so you can try adding + 1 to the date directly, once you strip the time component.
date_column >= trunc(sysdate) and
date_column < trunc(sysdate)+1
The best way to do this is to leave your MOPACTIVITY.MOPNOTIFICATIONSENDAT as a DATE type. That allows Oracle to optimize the query if there happens to be an index on the column. I'd recommend something like this:
WHERE MOPACTIVITY.MOPNOTIFICATIONSENDAT >= TRUNC(SYSDATE)
AND MOPACTIVITY.MOPNOTIFICATIONSENDAT < TRUNC(SYSDATE) + 1
That boils down to "greater than or equal to today at midnight" and "less than tomorrow at midnight".
We can also trunc both the dates and then compare the result
where TRUNC(MOPACTIVITY.MOPNOTIFICATIONSENDAT) = TRUNC(SYSDATE)
TRUNC Removes the timestamp from the dates