sql >> Databáze >  >> RDS >> Oracle

Jak v Oracle 11g vážete průměrná data každou hodinu mezi dvěma daty?

Používám vaše ukázková data – neměla data za celou hodinu, takže jsem udělal vážený průměr za minutu.

Nespecifikovali jste, co chcete na hranicích dělat, takže jsem vzal vážený průměr bezprostředně předcházejících a následujících hodnot.

SQL Fiddle

Nastavení schématu 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;

Dotaz 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

Výsledky :

|  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 |

UPRAVIT

SQL Fiddle

Nastavení schématu 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);

Dotaz 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

Výsledky :

|                      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 |


  1. Proč migrace Sequelize vytvořit tabulku, ale modely se nemohou připojit k databázi

  2. Funkce SQL Regex, která je podobná funkci MySql REGEX Function

  3. Třídit odrážky v databázi

  4. jednoduchý modul pro ověření přihlášení uživatele s uzlem