2017-04-06 69 views
0

我必须从Oracle表中获取数据,其中我有一个名为periodstarttime的日期字段,并且我只想获取汇总的数据(聚合必须完成1小时数据),在几分钟00þ,15日,30日,45在间隔5分钟oracle-从开始时间开始的1小时数据聚合15分钟的时间

例如与输入数据的一天,如果我的表我有periodstarttime作为

periodstarttime  data 
05/04/2017 1:00:00  10 
05/04/2017 1:05:00  1 
05/04/2017 1:10:00  2 
05/04/2017 1:15:00  3 
05/04/2017 1:20:00  4 
05/04/2017 1:25:00  5 
05/04/2017 1:30:00 
and so on.... 

那么我想我的结果看如:

periodstarttime   data with 1hr aggregation 
05/04/2017 1:00:00  data with 1hr aggregation from 1.00 to 2.00 
05/04/2017 1:15:00  data with 1hr aggregation from 1.15 to 2.15 
05/04/2017 1:30:00  data with 1hr aggregation from 1.30 to 2.30 
05/04/2017 1:45:00  data with 1hr aggregation from 1.45 to 2.45 
+1

创建实例以便你也可以给予预期的输出。 – Utsav

回答

0

您可以使用TRUNC()CASE截断到最近每隔15分钟,然后用解析函数与一窗口子句在滚动窗口得到的总和:

SELECT DISTINCT 
     periodstarttime, 
     SUM(data) OVER (ORDER BY periodstarttime 
          RANGE BETWEEN INTERVAL '0' MINUTE PRECEDING 
           AND  INTERVAL '45' MINUTE FOLLOWING 
         ) 
     AS hour_total, 
     'data with 1hr aggregation from ' 
     || TO_CHAR(periodstarttime, 'HH24:MI') 
     || ' to ' 
     || TO_CHAR(periodstarttime + INTERVAL '1' HOUR, 'HH24:MI') 
     AS range 
FROM (
    SELECT CASE 
      WHEN periodstarttime < TRUNC(periodstarttime, 'HH24') + INTERVAL '15' MINUTE 
      THEN TRUNC(periodstarttime, 'HH24') 
      WHEN periodstarttime < TRUNC(periodstarttime, 'HH24') + INTERVAL '30' MINUTE 
      THEN TRUNC(periodstarttime, 'HH24') + INTERVAL '15' MINUTE 
      WHEN periodstarttime < TRUNC(periodstarttime, 'HH24') + INTERVAL '45' MINUTE 
      THEN TRUNC(periodstarttime, 'HH24') + INTERVAL '30' MINUTE 
      ELSE TRUNC(periodstarttime, 'HH24') + INTERVAL '45' MINUTE 
     END AS periodstarttime, 
     data 
    FROM table_name 
) 
ORDER BY periodstarttime; 
+0

,但是当periodstarttime落在00和15之间时,生成的表格包含相同的periodstarttime两次或更多(00,0,0,10),但是我需要精确地聚合00,15,30,45,其中还包括05,10, 20,25 ...例如在一天中,我只需要96个样本(periodstarttime为00,15,30,45) – aaru

0

查看分析函数的Windowing_clause

会是这样

select periodstarttime, 
    SUM(DATA) OVER (RANGE BETWEEN CURRENT ROW AND INTERVAL '1' HOUR FOLLOWING ORDER BY periodstarttime), 
    'data with 1hr aggregation from '||FIRST_VALUE(periodstarttime) OVER (RANGE BETWEEN CURRENT ROW AND INTERVAL '1' HOUR FOLLOWING ORDER BY periodstarttime) 
    ||' to '||LAST_VALUE(periodstarttime) OVER (RANGE BETWEEN CURRENT ROW AND INTERVAL '1' HOUR FOLLOWING ORDER BY periodstarttime) 
FROM ... 
WHERE EXTRACT(MINUTE FROM periodstarttime) IN (0,15,30,45) 
+0

这有很多问题:15分钟内没有聚合(即,如果'11:00'条目丢失,那么'11:05'和'11:10'也将被忽略)。分析函数需要一个'ORDER BY'子句或者你得到'ORA-30485';如果'periodstarttime'是一个日期列,那么使用'MINUTE'作为'EXTRACT'的字段是无效的(它需要是一个'TIMESTAMP')。 – MT0

0

这里是做这件事的一种方法:

WITH your_table AS (SELECT to_date('05/04/2017 01:00:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 10 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:05:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 20 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:10:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 30 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:15:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 40 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:20:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 50 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:25:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 60 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:30:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 70 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:40:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 80 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 01:50:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 90 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 02:00:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 100 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 02:10:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 110 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 02:20:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 120 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 02:30:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 130 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 02:40:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 140 DATA FROM dual UNION ALL 
        SELECT to_date('05/04/2017 03:00:00', 'dd/mm/yyyy hh24:mi:ss') periodstarttime, 150 DATA FROM dual) 
-- End of setting up data in your_table; you would not need the above since you already have a table with data in it 
-- See the below SQL for the main statement: 
SELECT DISTINCT TRUNC(periodstarttime, 'hh') + FLOOR((TRUNC(periodstarttime, 'mi') - TRUNC(periodstarttime, 'hh'))/(15/1440))*15/1440 periodstarttime, 
     sum(DATA) OVER (ORDER BY TRUNC(periodstarttime, 'hh') + FLOOR((TRUNC(periodstarttime, 'mi') - TRUNC(periodstarttime, 'hh'))/(15/1440))*15/1440 
         RANGE BETWEEN 0 PRECEDING AND 60/1440 FOLLOWING) sum_over_next_hour 
FROM your_table 
ORDER BY periodstarttime; 

PERIODSTARTTIME SUM_OVER_NEXT_HOUR 
---------------- ------------------ 
05/04/2017 01:00    660 
05/04/2017 01:15    850 
05/04/2017 01:30    770 
05/04/2017 01:45    690 
05/04/2017 02:00    750 
05/04/2017 02:15    540 
05/04/2017 02:30    290 
05/04/2017 03:00    150 

这是通过:

  1. 寻找周期的开始时间,这是我们做的通过查找每个周期开始时间的分钟数,将其除以15分钟,找到该数字的底部,然后将其乘以新的号码15分钟。这将时间分成15个分钟组。

  2. 现在我们知道这些群体,我们可以做一个累计和。因为我们希望整个小时的价值,我们需要在当前时期和当前时期+ 1小时之间做一个范围。注:这是包容性的,因此02:00的值将包含在01:00期间的累积金额中。如果你不想这样做,请改变范围,使其达到59分钟(这很好,因为我们的时间段现在是过去一小时的0,15,30或45分钟)。

相关问题