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的解决方案可以正常工作.当然,这可以通过存储过程完成,但我希望在单个查询中完成任务.
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
编辑:像往常一样被贾斯汀击败...... :-)
就像是
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个间隔并对最低间隔进行硬编码.
| 归档时间: |
|
| 查看次数: |
7900 次 |
| 最近记录: |