Average Timestamp oracle with milliseconds - sql

Hello everyOne I need to get the AVERAGE of difference of two dates (timestamp)
I tried this
select AVG((sva.endTime - sva.startTime)) as seconds from SVATable sva;
but I got an error
93/5000
ORA-00932: Inconsistent data types; expected: NUMBER; got: INTERVAL DAY TO SECOND

You may use EXTRACT to get AVG seconds.
SELECT AVG (EXTRACT (SECOND FROM (sva.endTime - sva.startTime)))
AS avg_seconds
FROM SVATable sva;

This is an insidious problem in Oracle. Your calculation would work with the date data type, but it does not work with timestamps.
One solution is to extract the days, hours, minutes, and seconds from the interval. Another is to use date arithmetic. You can get fractions of a day by using:
select (date '2000-01-01' + (sva.endTime - sva.startTime)) - date '2000-01-01'
You can use the average and convert to seconds:
select avg( (date '2000-01-01' + (sva.endTime - sva.startTime)) - date '2000-01-01') * (60*60*24)

Related

How to get difference between two dates in days in postgres

Following is a query in oracle.
SELECT start_date - TO_DATE('1900-01-01','YYYY-MM-DD') FROM start_table
In oracle it gives the output 44680.3646, where start_date is 01-MAY-22.
what query would require to form to get the same output in EDB and postgresql
If you want to get the fractional part of a day, then you need to convert each value to number of seconds using EXTRACT(EPOCH FROM ...) and divide by 86400(number of seconds in 1 day) and then find the difference of the results.
SELECT extract(epoch from '2022-05-01 11:44:16'::timestamp - '1900-05-02'::timestamp) / 86400 as date
Result: 44559.489074074074
Demo in DBfiddle

How to calculate exact hours between two datetime fields?

I need to calculate hours between datetime fields and I can achieve it by simply doing
select date1,date2,(date1-date2) from table; --This gives answer in DD:HH:MM:SS format
select date1,date2,(trunc(date1)-trunc(date2))*24 --This doesn't take into account the time, it only gives hours between two dates.
Is there a way I can find the difference between date times that gives the output in Hours as a number?
The 'format' comment on your first query suggests your columns are timestamps, despite the dummy column names, as the result of subtracting two timestamps is an interval. Your second query is implicitly converting both timestamps to dates before subtracting them to get an answer as a number of days - which would be fractional if you weren't truncating them and thus losing the time portion.
You can extract the number of hours from the interval difference, and also 24 * the number of days if you expect it to exceed a day:
extract(day from (date1 - date2)) * 24 + extract(hour from (date1 - date2))
If you want to include fractional hours then you can extract and manipulate the minutes and seconds too.
You can also explicitly convert to dates, and truncate or floor after manipulation:
floor((cast(date1 as date) - cast(date2 as date)) * 24)
db<>fiddle demo
Use the DATEDIFF function in sql.
Example:
SELECT DATEDIFF(HOUR, '2021-09-05 12:00:00', GETDATE());
You can find it using the differnece of dates and multiplying with 24
select date1
,date2
,(date1-date2)*24 as diff_in_hrs
from table

Interval Date to days [duplicate]

I have two timestamp columns: arrTime and depTime.
I need to find the number of munites the bus is late.
I tried the following:
SELECT RouteDate, round((arrTime-depTime)*1440,2) time_difference
FROM ...
I get the following error: inconsistent datatype . expected number but got interval day to second
How can i parse the nuber of minutes?
If i simply subtract: SELECT RouteDate, arrTime-depTime)*1440 time_difference
The result is correct but not well formatted:
time_difference
+00000000 00:01:00 0000000
The result of timestamp arithmetic is an INTERVAL datatype. You have an INTERVAL DAY TO SECOND there...
If you want the number of minutes one way would be to use EXTRACT(), for instance:
select extract( minute from interval_difference )
+ extract( hour from interval_difference ) * 60
+ extract( day from interval_difference ) * 60 * 24
from ( select systimestamp - (systimestamp - 1) as interval_difference
from dual )
Alternatively you can use a trick with dates:
select sysdate + (interval_difference * 1440) - sysdate
from (select systimestamp - (systimestamp - 1) as interval_difference
from dual )
The "trick" version works because of the operator order of precedence and the differences between date and timestamp arithmetic.
Initially the operation looks like this:
date + ( interval * number ) - date
As mentioned in the documentation:
Oracle evaluates expressions inside parentheses before evaluating those outside.
So, the first operation performed it to multiply the interval by 1,440. An interval, i.e. a discrete period of time, multiplied by a number is another discrete period of time, see the documentation on datetime and interval arithmetic. So, the result of this operation is an interval, leaving us with:
date + interval - date
The plus operator takes precedence over the minus here. The reason for this could be that an interval minus a date is an invalid operation, but the documentation also implies that this is the case (doesn't come out and say it). So, the first operation performed is date + interval. A date plus an interval is a date. Leaving just
date - date
As per the documentation, this results in an integer representing the number of days. However, you multiplied the original interval by 1,440, so this now represented 1,440 times the amount of days it otherwise would have. You're then left with the number of seconds.
It's worth noting that:
When interval calculations return a datetime value, the result must be an actual datetime value or the database returns an error. For example, the next two statements return errors:
The "trick" method will fail, rarely but it will still fail. As ever it's best to do it properly.
SELECT (arrTime - depTime) * 1440 time_difference
FROM Schedule
WHERE ...
That will get you the time difference in minutes. Of course, you can do any rounding that you might need to to get whole minutes....
Casting to DATE first returns the difference as a number, at least with the version of Oracle I tried.
round((cast(arrTime as date) - cast(depTime as date))*1440)
You could use TO_CHAR then convert back to a number. I have never tested the performance compared to EXTRACT, but the statement works with two dates instead of an interval which fit my needs.
Seconds:
(to_char(arrTime,'J')-to_char(depTime,'J'))*86400+(to_char(arrTime,'SSSSS')-to_char(depTime,'SSSSS'))
Minutes:
round((to_char(arrTime,'J')-to_char(depTime,'J'))*1440+(to_char(arrTime,'SSSSS')-to_char(depTime,'SSSSS'))/60)
J is julian day and SSSSS is seconds in day. Together they give an absolute time in seconds.

presto - getting days interval (not date)

How do I get the days interval for prestodb? I can convert to milliseconds and convert these to number of days but I am looking if there is any shorter way to do this.
Example: I want to see how many days has it been since the first row inserted in a table.
SELECT
to_milliseconds(date(current_date) - min(created)) / (1000*60*60*24) as days_since_first_row
FROM
some_table
What I am hoping to see: (Either 1 of below)
SELECT
to_days(date(current_date) - min(created)) / (1000*60*60*24) as days_since_first_row
,cast(date(current_date) - min(created)) as days) as days_since_first_row2
FROM
some_table
Unfortunately, daylight savings breaks the solution from the accepted answer. DAY(DATE '2020-09-6' - DATE '2020-03-09') and DAY(DATE '2020-09-6' - DATE '2020-03-08') are both equal to 181 due to daylight savings time and DAY acting as a floor function on timestamps.
Instead, use DATE_DIFF:
DATE_DIFF('day', DATE '2020-09-6', DATE '2020-03-09')
Use subtraction to obtain an interval and then use day on the interval to get number of days elapsed.
presto:default> select day(current_date - date '2018-07-01');
_col0
-------
86
The documentation for this is at https://trino.io/docs/current/functions/datetime.html

Avg of time in Oracle SQL

I'm trying to find out avg time of when a particular task is getting completed.I can ignore date because the task will complete everyday.
So, I'm trying to find out when the job is getting complete on avg like 4:45:50
My Data:
28-AUG-2015 01.24.58.000000000 AM
27-AUG-2015 01.31.33.000000000 AM
26-AUG-2015 01.28.09.000000000 AM
25-AUG-2015 01.30.43.000000000 AM
24-AUG-2015 01.02.46.000000000 AM
23-AUG-2015 01.18.56.000000000 AM
22-AUG-2015 01.25.24.000000000 AM
21-AUG-2015 01.30.07.000000000 AM
20-AUG-2015 01.25.58.000000000 AM
19-AUG-2015 01.27.08.000000000 AM
18-AUG-2015 01.28.12.000000000 AM
17-AUG-2015 01.27.51.000000000 AM
16-AUG-2015 01.34.32.000000000 AM
15-AUG-2015 01.46.10.000000000 AM
14-AUG-2015 01.56.47.000000000 AM
13-AUG-2015 01.38.55.000000000 AM
There has to be a better way, but this should work:
select to_char(trunc(sysdate) +
avg(cast(your_timestamp as date) - cast(trunc(your_timestamp) as date))
, 'hh:mi:ss PM')
from your_table
Steps:
cast(your_timestamp as date) - cast(trunc(your_timestamp) as date): Calculate the date's time offset since midnight. (I cast to date so that the arithmetic returns a number instead of an interval, which allows step #2 to work).
avg(...): get the average time offset since midnight (Can't do avg over a time interval. That's why I'm using dates)
trunc(sysdate) + ...: Construct a valid date using the average time offset from step #2.
to_char(..., 'hh:mi:ss PM'): Extract the time portion for display.