在给定时间间隔内的聚合函数

Nic*_*ick 8 sql oracle aggregate oracle10g

我的SQL有点生疏,我遇到这个问题有点困难.假设我有一个带有Timestamp列和Number列的表.目标是返回包含某个任意选择的常规间隔的平均值的结果集.

因此,例如,如果我有以下初始数据,则间隔为5分钟的结果输出如下:

time                               value
-------------------------------    -----
06-JUN-12 12.40.00.000000000 PM      2
06-JUN-12 12.41.35.000000000 PM      3
06-JUN-12 12.43.22.000000000 PM      4
06-JUN-12 12.47.55.000000000 PM      5
06-JUN-12 12.52.00.000000000 PM      2
06-JUN-12 12.54.59.000000000 PM      3
06-JUN-12 12.56.01.000000000 PM      4

OUTPUT:

start_time                         avg_value
-------------------------------    ---------
06-JUN-12 12.40.00.000000000 PM      3
06-JUN-12 12.45.00.000000000 PM      5
06-JUN-12 12.50.00.000000000 PM      2.5
06-JUN-12 12.55.00.000000000 PM      4
Run Code Online (Sandbox Code Playgroud)

请注意,这是一个Oracle数据库,因此特定于Oracle的解决方案可以正常工作.当然,这可以通过存储过程完成,但我希望在单个查询中完成任务.

Seb*_*bas 8

CREATE TABLE tt (time TIMESTAMP, value NUMBER);

INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.40.00.000000000 PM', 2);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.41.35.000000000 PM', 3);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.43.22.000000000 PM', 4);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.47.55.000000000 PM', 5);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.52.00.000000000 PM', 2);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.54.59.000000000 PM', 3);
INSERT INTO tt (time, value) VALUES ('06-JUN-12 12.56.01.000000000 PM', 4);


WITH tmin AS (
    SELECT MIN(time) t FROM tt
),   tmax AS (
    SELECT MAX(time) t FROM tt
)
SELECT ranges.inf, ranges.sup, AVG(tt.value)
FROM
     (
        SELECT 
            5*(level-1)*(1/24/60) + tmin.t as inf,
            5*(level)*(1/24/60) + tmin.t as sup
        FROM tmin, tmax
        CONNECT BY (5*(level-1)*(1/24/60) + tmin.t) < tmax.t
    ) ranges JOIN tt ON tt.time BETWEEN ranges.inf AND ranges.sup
GROUP BY ranges.inf, ranges.sup
ORDER BY ranges.inf
Run Code Online (Sandbox Code Playgroud)

小提琴:http://sqlfiddle.com/#!4/ 9e314/11

编辑:像往常一样被贾斯汀击败...... :-)


Jus*_*ave 5

就像是

with st 
  as (SELECT to_timestamp( '2012-06-06 12:40:00', 'yyyy-mm-dd hh24:mi:ss') + 
               numtodsinterval((level-1)*5, 'MINUTE') start_time,
             to_timestamp( '2012-06-06 12:40:00', 'yyyy-mm-dd hh24:mi:ss') + 
               numtodsinterval(level*5, 'MINUTE') end_time
        from dual
     connect by level <= 10)
SELECT st.start_time, avg( yt.value )
  FROM your_table yt,
       st
 WHERE yt.time between st.start_time and st.end_time
Run Code Online (Sandbox Code Playgroud)

应该管用.您可以增强查询以从表中MIN(time)MAX(time)表中派生起始点和行数,而不是生成10个间隔并对最低间隔进行硬编码.