Averaging a list of TIMESTAMP(6) WITH TIME ZONE times

感情迁移 提交于 2020-01-06 03:31:27

问题


I've got 2 columns in a database of type TIMESTAMP(6) WITH TIME ZONE. I've subtracted one from the other to get the time between the two timestamps.

select lastprocesseddate-importeddate 
from feedqueueitems 
where eventid = 2213283 
order by written desc;

How can I get an average of the list of time differences I have?

Here are a small sample of time differences:

+00 00:00:00.488871    
+00 00:00:00.464286  
+00 00:00:00.477107  
+00 00:00:00.507042  
+00 00:00:00.369144  
+00 00:00:00.488918  
+00 00:00:00.354797  
+00 00:00:00.378801  
+00 00:00:00.320040  
+00 00:00:00.361242  
+00 00:00:00.302327  
+00 00:00:00.331441  
+00 00:00:00.324065

EDIT: I also should have noted - I've tried the AVG function, and it just returns

ORA-00932: inconsistent datatypes: expected NUMBER got INTERVAL DAY TO SECOND
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
*Cause:    
*Action:
Error at Line: 3 Column: 29

EDIT2: Just to clarify the above snippet. Line 3 is my SQL query all on one line in the following format:

select AVG(lastprocesseddate-importeddate) from feedqueueitems where eventid = 2213283;

EDIT3: Massive thanks to Matt and Alex Poole. You've both helped massively and I appreciate you taking the time to help with this and to both consistently return with updated help in response to the feedback/further problems! Thanks guys!


回答1:


Use the AVG function

SELECT avg(cast(lastprocesseddate as date)-cast(importeddate as date))
FROM feedqueueitems 
WHERE eventid = 2213283 
ORDER BY written DESC;

On the Database with the +1 timezone for importeddate and lastprocesseddate is UTC

SELECT avg(cast(cast(lastprocesseddate as timestamp with time zone) at time zone '+01:00' as date)-cast(importeddate as date))
FROM feedqueueitems 
WHERE eventid = 2213283 
ORDER BY written DESC;



回答2:


You could extract the time components from each gap value, which is an interval data type, so you end up with a figure in seconds (including the fractional part), and then average those:

select avg(extract(second from gap)
    + extract(minute from gap) * 60
    + extract(hour from gap) * 60 * 60
    + extract(day from gap) * 60 * 60 * 24) as avg_gap
from (
  select lastprocesseddate-importeddate as gap
  from feedqueueitems
  where eventid = 2213283
);

A demo using a CTE to provide the interval values you showed:

with cte as (
  select interval '+00 00:00:00.488871' day to second as gap from dual
  union all select interval '+00 00:00:00.464286' day to second from dual
  union all select interval '+00 00:00:00.477107' day to second from dual
  union all select interval '+00 00:00:00.507042' day to second from dual
  union all select interval '+00 00:00:00.369144' day to second from dual
  union all select interval '+00 00:00:00.488918' day to second from dual
  union all select interval '+00 00:00:00.354797' day to second from dual 
  union all select interval '+00 00:00:00.378801' day to second from dual
  union all select interval '+00 00:00:00.320040' day to second from dual
  union all select interval '+00 00:00:00.361242' day to second from dual
  union all select interval '+00 00:00:00.302327' day to second from dual
  union all select interval '+00 00:00:00.331441' day to second from dual
  union all select interval '+00 00:00:00.324065' day to second from dual
)
select avg(extract(second from gap)
    + extract(minute from gap) * 60
    + extract(hour from gap) * 60 * 60
    + extract(day from gap) * 60 * 60 * 24) as avg_gap
from cte;

   AVG_GAP
----------
.397544692

Or if you wanted it as an interval:

select numtodsinterval(avg(extract(second from gap)
    + extract(minute from gap) * 60
    + extract(hour from gap) * 60 * 60
    + extract(day from gap) * 60 * 60 * 24), 'SECOND') as avg_gap
...

which gives

AVG_GAP            
--------------------
0 0:0:0.397544692   

SQL Fiddle with answer in seconds. (It doesn't seem to like displaying intervals at the moment, so can't demo that).




回答3:


This query should solve the issue.

WITH t AS 
    (SELECT 
        TIMESTAMP '2015-04-23 12:00:00.5 +02:00' AS lastprocesseddate,  
        TIMESTAMP '2015-04-23 12:05:10.21 UTC' AS importeddate 
    FROM dual)
SELECT 
    AVG(
        EXTRACT(SECOND FROM SYS_EXTRACT_UTC(lastprocesseddate) - SYS_EXTRACT_UTC(importeddate))
        + EXTRACT(MINUTE FROM SYS_EXTRACT_UTC(lastprocesseddate) - SYS_EXTRACT_UTC(importeddate)) * 60
        + EXTRACT(HOUR FROM SYS_EXTRACT_UTC(lastprocesseddate) - SYS_EXTRACT_UTC(importeddate)) * 60 * 60
        + EXTRACT(DAY FROM SYS_EXTRACT_UTC(lastprocesseddate) - SYS_EXTRACT_UTC(importeddate)) * 60 * 60 * 24
    ) AS average_gap
FROM t;


来源:https://stackoverflow.com/questions/29820309/averaging-a-list-of-timestamp6-with-time-zone-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!