Używając Twoich przykładowych danych – nie zawierał danych z pełnej godziny, więc zrobiłem średnią ważoną na minutę.
Nie określiłeś, co chcesz zrobić na granicach, więc wziąłem średnią ważoną bezpośrednio poprzedzających i następujących wartości.
Konfiguracja schematu Oracle 11g R2 :
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;
Zapytanie 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
Wyniki :
| 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 |
EDYTUJ
Konfiguracja schematu Oracle 11g R2 :
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);
Zapytanie 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
Wyniki :
| 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 |