我必须从Oracle Table获取数据,其中我有一个名为periodstarttime
的日期字段,我想在第00,15,30,45分钟只获取聚合数据(聚合必须在1小时内完成数据)在一天内以5分钟的间隔输入数据
例如,如果在我的表中我将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
答案 0 :(得分: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)
答案 1 :(得分: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
这适用于:
找到期间开始时间,我们通过查找每个期间的分钟时间,将其除以15分钟,找到该平均值,然后将该新数字乘以15分钟。这将时间分为15分钟组。
现在我们知道这些团体,我们可以做累积总和。因为我们想要跨越一小时的值,我们需要在当前时段和当前时段+ 1小时之间进行范围。注:这是包含性的,因此02:00值将包含在01:00期间的累计总和中。如果您不想这样做,请更改范围,使其达到59分钟(这很好,因为我们的时间段现在是小时的0,15,30或45分钟)。
答案 2 :(得分: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;