我把原来的问题换成了这个最终答案。在MTO先生和Ponder Stibbons先生的帮助下,在我的oracle 11G实例上花了四个月的时间,我终于得到了您在这里看到的东西。这个查询主要是为SCADA系统设计的,它将执行以下操作…
此查询将在两个日期时间之间执行时间加权平均每小时作为TWA,最小值和最大值在该间隔内作为Vmin和Vmax。它还将返回最小时间和最大时间作为Hmin和Hmax。(这些是最小值发生和最大值发生的日期时间)。起始和结束间隔值如VSTART和VEND。此查询在3月或8月的夏令时不会失败。(这就是为什么我使用TO_TIMESTAMP_TZ)
注意:此查询设置为1小时间隔,任何所需的间隔都可以通过替换和添加几个项目来实现。所以享受! !
这个查询在我的Oracle 11g实例中工作,在写完这篇文章后,我复制了下面的确切文本并粘贴到我的SQL Developer中。所以它是有效的!!我在sqlfiddle中运行这个有麻烦,但很快我会弄清楚这一点,并为您进行运行测试。
SQL小提琴 -- Lets Begin the Query
WITH INPUTS AS (
SELECT RECNM,
TO_TIMESTAMP_TZ ( '01-JAN-15 00:00:00 AMERICA/LOS_ANGELES','DD-MON-RR HH24:MI:SS TZR' ) AS START_TIME,
TO_TIMESTAMP_TZ ( '06-NOV-15 23:59:59 AMERICA/LOS_ANGELES','DD-MON-RR HH24:MI:SS TZR' ) AS END_TIME
FROM POINTS
WHERE ACRONYM = 'WELL32-PSI'
) ,
ALL_INTERVALS AS (
SELECT RECNM,
START_TIME + NUMTODSINTERVAL ( ( LEVEL-1 ) , 'HOUR' ) AS TIME
FROM INPUTS
CONNECT BY
LEVEL-1 <=
EXTRACT ( DAY FROM END_TIME - START_TIME ) * 24 +
EXTRACT ( HOUR FROM END_TIME - START_TIME )
) ,
ALL_TIMES AS (
SELECT
TIME,
VALUE,
1 AS HAS_VALUE
FROM HST H
INNER JOIN INPUTS I
ON ( H.RECNM = I.RECNM
AND H.TIME BETWEEN CAST ( I.START_TIME AS TIMESTAMP )
AND CAST ( I.END_TIME AS TIMESTAMP ) )
UNION ALL
SELECT
TIME,
NULL,
0
FROM ALL_INTERVALS
ORDER BY TIME,1, 2 NULLS FIRST
) ,
LEAD_LAG_TIMES AS (
SELECT
TIME,
LAST_VALUE ( VALUE IGNORE NULLS ) OVER ( ORDER BY TIME ASC, VALUE ASC ) AS VALUE,
24 * 60 * 60 * EXTRACT ( DAY FROM LEAD ( TIME ) OVER ( ORDER BY TIME ASC,VALUE ASC ) -TIME ) +
60 * 60 * EXTRACT ( HOUR FROM LEAD ( TIME ) OVER ( ORDER BY TIME ASC,VALUE ASC ) -TIME ) +
60 * EXTRACT ( MINUTE FROM LEAD ( TIME ) OVER ( ORDER BY TIME ASC,VALUE ASC ) -TIME ) +
EXTRACT ( SECOND FROM LEAD ( TIME ) OVER ( ORDER BY TIME ASC,VALUE ASC ) -TIME ) AS DURATION
FROM ALL_TIMES
)
SELECT CAST ( TRUNC ( TIME,'HH24' ) AS TIMESTAMP WITH TIME ZONE ) AS TIME,
SUM ( VALUE * DURATION ) / SUM ( DURATION ) AS TWA,
MIN ( VALUE ) AS VMIN,
MAX ( TIME ) KEEP ( DENSE_RANK LAST ORDER BY VALUE DESC ) AS TMIN,
MAX ( VALUE ) AS VMAX,
MAX ( TIME ) KEEP ( DENSE_RANK LAST ORDER BY VALUE ASC ) AS TMAX,
SUM ( VALUE ) AS TOTAL,
MAX ( VALUE ) KEEP (DENSE_RANK FIRST ORDER BY TIME ASC) as VSTART,
MAX ( VALUE ) KEEP (DENSE_RANK LAST ORDER BY TIME ASC) as VEND,
SUM ( DURATION ) AS TOTAL_DURATION
FROM LEAD_LAG_TIMES
GROUP BY CAST ( TRUNC ( TIME,'HH24' ) AS TIMESTAMP WITH TIME ZONE )
ORDER BY TIME ASC
编辑:您可以将此包含在时间加权的1小时滚动平均值的最终选择语句中!我发现这在废水行业非常有用,因为州法规/报告要求24小时滚动平均值和72分钟滚动平均值。如果需要24个滚动平均值,将ROWS 1 proceed更改为ROWS 24 proceed
ROUND( AVG ( SUM ( value * DURATION ) / sum ( DURATION ) ) OVER (ORDER BY CAST ( TRUNC ( TIME,'hh24' ) AS TIMESTAMP WITH TIME ZONE ), CAST ( TRUNC ( TIME,'hh24' ) AS TIMESTAMP WITH TIME ZONE ) ROWS 1 PRECEDING),2) AS ROLLING_1H_VAVG,
标准偏差很有趣,所以也要加上这个。
ROUND( STDDEV ( VALUE ) , 2 ) as VDEV,
如果您需要在开始时间之前和结束时间之后的值,您可以将此值与其他联合的all's放在一起。
UNION ALL
SELECT
MAX(H.TIME) KEEP (DENSE_RANK FIRST ORDER BY H.TIME DESC) AS TIME,
MAX(H.VALUE) KEEP (DENSE_RANK FIRST ORDER BY H.TIME DESC),
1
FROM INPUTS I
INNER JOIN HST H
ON H.TIME < I.START_TIME
UNION ALL
SELECT
MIN(H.TIME) KEEP (DENSE_RANK FIRST ORDER BY H.TIME) AS TIME,
MIN(H.VALUE) KEEP (DENSE_RANK FIRST ORDER BY H.TIME),
1
FROM INPUTS I
INNER JOIN HST H
ON H.TIME > I.END_TIME
使用您的样本数据-它没有完整小时的数据,所以我做了每分钟的加权平均值。
你没有指定你想在边界处做什么,所以我取了前面和后面的值的加权平均值。
SQL小提琴Oracle 11g R2 Schema Setup:
CREATE TABLE TEST ( Acronym, Date_Time, Value ) AS
SELECT '32-PRESS', TIMESTAMP '15-01-01 00:00:07.120000000', 63.7363 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:00:17.088000000', 64.5604 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:00:27.864000000', 66.3004 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:00:45.080000000', 66.804 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:00:55.056000000', 67.4908 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:01:11.384000000', 66.9872 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:01:30.424000000', 67.4451 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:01:40.408000000', 67.9487 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:01:50.408000000', 68.6813 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:01.304000000', 68.1777 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:11.304000000', 67.1245 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:21.264000000', 66.5293 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:31.232000000', 65.4762 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:45.736000000', 65.0183 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:02:59.312000000', 64.5604 FROM DUAL
UNION ALL SELECT '32-PRESS', TIMESTAMP '15-01-01 00:03:14.712000000', 64.1026 FROM DUAL;
查询1 :
WITH temp AS (
SELECT ACRONYM,
DATE_TIME,
VALUE
FROM TEST
UNION
SELECT ACRONYM,
TO_TIMESTAMP( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' ),
NULL
FROM TEST
GROUP BY
ACRONYM,
TO_TIMESTAMP( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' )
UNION
SELECT ACRONYM,
TO_TIMESTAMP( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' ) + INTERVAL '1' MINUTE,
NULL
FROM TEST
GROUP BY
ACRONYM,
TO_TIMESTAMP( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' )
ORDER BY
1,2
),
temp2 AS (
SELECT ACRONYM,
DATE_TIME,
COALESCE(
VALUE,
COALESCE(
LAG( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME ),
LEAD( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME )
)
+
(
COALESCE(
LEAD( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME ),
LAG( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME )
)
-
COALESCE(
LAG( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME ),
LEAD( VALUE ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME )
)
)
*
EXTRACT( SECOND FROM ( DATE_TIME - LAG( DATE_TIME, 1, DATE_TIME ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME ) ) )
/
EXTRACT( SECOND FROM (
LEAD( DATE_TIME, 1, DATE_TIME ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME )
-
LAG( DATE_TIME, 1, DATE_TIME ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME )
) )
) AS VALUE,
LEAD( DATE_TIME ) OVER ( PARTITION BY ACRONYM ORDER BY DATE_TIME ) AS NEXT_DATE_TIME
FROM temp
)
SELECT ACRONYM,
TO_DATE( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' ) AS DATE_TIME,
SUM( VALUE * EXTRACT( SECOND FROM ( NEXT_DATE_TIME - DATE_TIME ) ) ) / 60 AS VALUE
FROM temp2
WHERE NEXT_DATE_TIME IS NOT NULL
GROUP BY
ACRONYM,
TO_DATE( TO_CHAR( DATE_TIME, 'YYYY-MM-DD HH24:MI' ), 'YYYY-MM-DD HH24:MI' )
ORDER BY
1,2
结果:
| ACRONYM | DATE_TIME | VALUE |
|----------|---------------------------|-------------------|
| 32-PRESS | January, 01 0015 00:00:00 | 65.43946117333333 |
| 32-PRESS | January, 01 0015 00:01:00 | 67.56109262835211 |
| 32-PRESS | January, 01 0015 00:02:00 | 66.32093658633383 |
| 32-PRESS | January, 01 0015 00:03:00 | 64.20983764043636 |
编辑
SQL小提琴Oracle 11g R2 Schema Setup:
CREATE TABLE POINTS ( RECNM NUMBER, ACRONYM VARCHAR2(20) );
INSERT INTO POINTS VALUES(1136, '32-PRESS');
INSERT INTO POINTS VALUES(1138, 'OTHER_POINT');
CREATE TABLE HST ( RECNM NUMBER, TIME TIMESTAMP, VALUE NUMBER );
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:00',63.3);
INSERT INTO HST VALUES(1138, TIMESTAMP '15-01-01 00:00:00',0.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:07',63.7);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:17',64.6);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:28',66.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:45',66.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:00:55',67.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:01:11',67.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:01:30',67.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:01:40',67.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:01:50',68.7);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:01',68.2);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:11',67.1);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:21',66.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:31',65.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:46',65.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:02:59',64.6);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:03:15',64.1);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:03:25',63.2);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:03:35',62.7);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:04:05',62.2);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:04:32',61.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:05:40',61.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:05:55',60.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:10:20',60.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:10:38',60.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:10:48',61.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:10:58',61.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:11:27',62.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:13:54',61.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:14:10',61.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:14:41',60.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:15:18',61.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:15:51',60.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:16:19',60.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:16:32',59.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:17:04',59.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:17:27',59.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:17:37',59.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:17:58',59.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:18:22',59.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:18:50',59.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:19:00',60.3);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:19:25',60.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:19:34',61.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:19:45',62.1);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:19:55',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:20:30',63.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:20:51',63.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:21:03',63.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:22:04',64.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:22:28',64.8);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:23:17',64.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:23:27',63.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:24:31',63.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:26:06',63.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:27:20',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:27:30',61.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:28:08',62.4);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:28:37',62.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:29:21',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:29:38',62.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:31:27',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:32:01',62.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:32:25',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:35:07',62.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:35:56',62.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:36:06',62.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:36:59',61.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:39:31',62.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:40:12',61.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:40:22',60.9);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:40:35',60.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:40:55',60.0);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:41:22',60.5);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:41:46',60.1);
INSERT INTO HST VALUES(1136, TIMESTAMP '15-01-01 00:42:31',60.6);
查询1 :
WITH inputs AS (
SELECT RECNM,
TIMESTAMP '15-01-01 00:00:00' AS start_time,
TIMESTAMP '15-01-01 00:40:00' AS end_time
FROM POINTS
WHERE ACRONYM = '32-PRESS'
),
all_minutes AS (
SELECT RECNM,
start_time + (LEVEL-1)/24/60 AS time
FROM inputs
CONNECT BY
LEVEL - 1 <= EXTRACT( MINUTE FROM end_time - start_time )
),
all_times AS (
SELECT TIME,
VALUE,
1 AS HAS_VALUE
FROM HST h
INNER JOIN inputs i
ON ( h.RECNM = i.RECNM
AND h.TIME BETWEEN i.start_time
AND i.end_time )
UNION ALL
SELECT TIME,
NULL,
0
FROM all_minutes
ORDER BY 1, 2 NULLS FIRST
),
lag_lead_ignore_nulls AS (
SELECT TIME,
VALUE,
COUNT( VALUE ) OVER ( ORDER BY TIME ASC, VALUE ASC NULLS FIRST ) AS LAG_GRP,
COUNT( VALUE ) OVER ( ORDER BY TIME DESC, VALUE DESC NULLS LAST ) AS LEAD_GRP
FROM all_times
),
lag_lead_values AS (
SELECT TIME,
VALUE,
FIRST_VALUE( TIME ) OVER ( PARTITION BY LAG_GRP ORDER BY VALUE ASC NULLS LAST ) AS PREV_MEASURED_TIME,
FIRST_VALUE( VALUE ) OVER ( PARTITION BY LAG_GRP ORDER BY VALUE ASC NULLS LAST ) AS PREV_MEASURED_VALUE,
FIRST_VALUE( TIME ) OVER ( PARTITION BY LEAD_GRP ORDER BY VALUE ASC NULLS LAST ) AS NEXT_MEASURED_TIME,
FIRST_VALUE( VALUE ) OVER ( PARTITION BY LEAD_GRP ORDER BY VALUE ASC NULLS LAST ) AS NEXT_MEASURED_VALUE,
LEAD( TIME ) OVER ( ORDER BY TIME ASC ) AS NEXT_TIME
FROM lag_lead_ignore_nulls
),
interpolated_values AS (
SELECT CAST( TIME AS DATE ) TIME,
COALESCE(
VALUE,
PREV_MEASURED_VALUE
+ ( NEXT_MEASURED_VALUE - PREV_MEASURED_VALUE )
* (
60 * EXTRACT( MINUTE FROM TIME - PREV_MEASURED_TIME )
+ EXTRACT( SECOND FROM TIME - PREV_MEASURED_TIME )
)
/ (
60 * EXTRACT( MINUTE FROM NEXT_MEASURED_TIME - PREV_MEASURED_TIME )
+ EXTRACT( SECOND FROM NEXT_MEASURED_TIME - PREV_MEASURED_TIME )
)
) AS INTERPOLATED_VALUE,
60 * EXTRACT( MINUTE FROM NEXT_TIME - TIME )
+ EXTRACT( SECOND FROM NEXT_TIME - TIME ) AS DURATION
FROM lag_lead_values
)
SELECT TRUNC( TIME, 'MI' ) AS TIME,
SUM( INTERPOLATED_VALUE * DURATION ) / SUM( DURATION ) AS TWA,
SUM( DURATION ) AS TOTAL_DURATION
FROM interpolated_values
WHERE INTERPOLATED_VALUE IS NOT NULL
GROUP BY TRUNC( TIME, 'MI' )
ORDER BY TIME ASC
结果:
| TIME | TWA | TOTAL_DURATION |
|---------------------------|--------------------|----------------|
| January, 01 0015 00:00:00 | 65.38833333333333 | 60 |
| January, 01 0015 00:01:00 | 67.56302083333334 | 60 |
| January, 01 0015 00:02:00 | 66.30575757575758 | 60 |
| January, 01 0015 00:03:00 | 63.48385416666667 | 60 |
| January, 01 0015 00:04:00 | 62.02027777777778 | 60 |
| January, 01 0015 00:05:00 | 61.45441176470588 | 60 |
| January, 01 0015 00:06:00 | 60.79056603773585 | 60 |
| January, 01 0015 00:07:00 | 60.677358490566036 | 60 |
| January, 01 0015 00:08:00 | 60.56415094339623 | 60 |
| January, 01 0015 00:09:00 | 60.450943396226414 | 60 |
| January, 01 0015 00:10:00 | 60.62924528301887 | 60 |
| January, 01 0015 00:11:00 | 62.09051724137931 | 60 |
| January, 01 0015 00:12:00 | 62.18775510204082 | 60 |
| January, 01 0015 00:13:00 | 61.96530612244898 | 60 |
| January, 01 0015 00:14:00 | 61.28333333333333 | 60 |
| January, 01 0015 00:15:00 | 61.252027027027026 | 60 |
| January, 01 0015 00:16:00 | 60.27410714285714 | 60 |
| January, 01 0015 00:17:00 | 59.47416666666667 | 60 |
| January, 01 0015 00:18:00 | 59.34888888888889 | 60 |
| January, 01 0015 00:19:00 | 61.06 | 60 |
| January, 01 0015 00:20:00 | 62.86071428571429 | 60 |
| January, 01 0015 00:21:00 | 63.895 | 60 |
| January, 01 0015 00:22:00 | 64.61114754098361 | 60 |
| January, 01 0015 00:23:00 | 64.16431972789115 | 60 |
| January, 01 0015 00:24:00 | 63.52513020833333 | 60 |
| January, 01 0015 00:25:00 | 63.27789473684211 | 60 |
| January, 01 0015 00:26:00 | 63.002526315789474 | 60 |
| January, 01 0015 00:27:00 | 62.245045045045046 | 60 |
| January, 01 0015 00:28:00 | 62.23263157894737 | 60 |
| January, 01 0015 00:29:00 | 62.56314393939394 | 60 |
| January, 01 0015 00:30:00 | 62.81926605504587 | 60 |
| January, 01 0015 00:31:00 | 62.544587155963306 | 60 |
| January, 01 0015 00:32:00 | 62.29191176470588 | 60 |
| January, 01 0015 00:33:00 | 62.58641975308642 | 60 |
| January, 01 0015 00:34:00 | 62.73456790123457 | 60 |
| January, 01 0015 00:35:00 | 62.87131687242798 | 60 |
| January, 01 0015 00:36:00 | 62.02166666666667 | 60 |
| January, 01 0015 00:37:00 | 61.50328947368421 | 60 |
| January, 01 0015 00:38:00 | 61.70065789473684 | 60 |
| January, 01 0015 00:39:00 | 61.94731359649123 | 60 |
这个查询生成了期望的值:
with input as (
select value, htime, to_char(htime, 'yyyy-mm-dd hh24:mi') mnt,
extract(day from d)+extract(hour from d)/24+
extract(minute from d)/(24*60)+extract (second from d)/(24*60*60) tm
from (select value, htime, htime-timestamp '1899-12-30 00:00:00' d from test))
select distinct mnt, round(
sum(tm*value) over (partition by mnt)/sum(tm) over (partition by mnt), 6) wav
from input order by mnt
输出:MNT WAV
---------------- ----------
2015-01-01 12:00 65.77838
2015-01-01 12:01 67.765575
2015-01-01 12:02 66.147733
2015-01-01 12:03 64.1026
<一口> SQLFiddle 一口>
根据文档,Excel日历以'1900-01-01'开头,但我必须稍微修改这个日期,以实现"日期零",以获得与电子表格中完全相同的时差数值。剩下的只需要减去时间戳,将这个差值转换为数字,并在解析版本中使用函数sum()
对每分钟的结果求和。
如果你的数据中有空白,你需要首先用递归查询(connect by
)为每分钟创建周期,然后用函数lag(wav ignore nulls)
收集前一分钟(s)的加权平均值将该查询与空白的矿区填充数据左连接。
编辑:版本填充空白:
with input as (
select value, htime, to_char(htime, 'yyyy-mm-dd hh24:mi') mnt,
extract(day from d)+extract(hour from d)/24+
extract(minute from d)/(24*60)+extract (second from d)/(24*60*60) tm
from (select value, htime, htime-timestamp '1899-12-30 00:00:00' d from data)),
period as (select to_date(min(mnt), 'yyyy-mm-dd hh24:mi') m1,
to_date(max(mnt), 'yyyy-mm-dd hh24:mi') m2 from input),
minutes as (
select to_char(to_date(m1) + (level - 1)/(24*60), 'yyyy-mm-dd hh24:mi') mnt
from period connect by level+1<(m2-m1)*24*60),
calc as (
select distinct mnt,
round(sum(tm*value) over (partition by mnt)/sum(tm) over (partition by mnt), 6) wav
from minutes left join input using (mnt) order by mnt)
select mnt, wav, nvl(wav, lag(wav ignore nulls) over (order by mnt)) wavg from calc
<一口> SQLFiddle 一口>
子查询input
准备数据进行进一步处理,period
从表中选择min和max minute(你可以在这里手工插入一些值,而不是从表中查询,例如"date '2015-01-01 13:52:00'"),minutes
生成……对于给定时间段,calc
对输入和分钟数进行加权平均,last select填充空分钟的最后已知平均值-您可以在SQLFiddle中观察分钟6,7,12。