sql >> データベース >  >> RDS >> Oracle

時間間隔でのSQLグループ化

    WITH changes AS (
      SELECT "DATE",
             CASE WHEN LAG( "DATE" ) OVER ( ORDER BY "DATE" ) + INTERVAL '5' MINUTE = "DATE" THEN 0 ELSE 1 END AS has_changed_group
      FROM   TEST
    ), grps AS (
      SELECT "DATE",
             SUM( has_changed_group ) OVER ( ORDER BY "DATE" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS grp
      FROM   changes
    )
    SELECT MIN( "DATE" ) AS shutdown_start,
           MAX( "DATE" ) AS shutdown_end,
           MAX( "DATE" ) - MIN( "DATE" ) + INTERVAL '5' MINUTE AS shutdown_duration
    FROM   grps
    GROUP BY grp;
    

    出力:

    SHUTDOWN_START               SHUTDOWN_END                 SHUTDOWN_DURATION
    ---------------------------- ---------------------------- -----------------
    07-JUL-15 12.05.00.000000000 07-JUL-15 12.15.00.000000000 0 0:15:0.0        
    07-JUL-15 12.35.00.000000000 07-JUL-15 12.50.00.000000000 0 0:20:0.0        
    07-JUL-15 13.05.00.000000000 07-JUL-15 13.15.00.000000000 0 0:15:0.0  
    

    編集-複数のマシン:

    SQLフィドル

    Oracle11gR2スキーマのセットアップ

    CREATE TABLE TEST ( MACHINE_ID, "DATE" ) AS
              SELECT 1, TIMESTAMP '2015-07-07 12:05:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:10:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:15:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:35:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:40:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:45:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 12:50:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 13:05:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 13:10:00' FROM DUAL
    UNION ALL SELECT 1, TIMESTAMP '2015-07-07 13:15:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 12:35:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 12:40:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 12:45:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 13:00:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 13:05:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 13:10:00' FROM DUAL
    UNION ALL SELECT 2, TIMESTAMP '2015-07-07 13:15:00' FROM DUAL;
    

    クエリ1

    WITH changes AS (
      SELECT MACHINE_ID,
             "DATE",
             CASE WHEN LAG( "DATE" ) OVER ( PARTITION BY MACHINE_ID ORDER BY "DATE" ) + INTERVAL '5' MINUTE = "DATE" THEN 0 ELSE 1 END AS has_changed_group
      FROM   TEST
    ), grps AS (
      SELECT MACHINE_ID,
             "DATE",
             SUM( has_changed_group ) OVER ( PARTITION BY MACHINE_ID ORDER BY "DATE" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS grp
      FROM   changes
    )
    SELECT MACHINE_ID,
           TO_CHAR( MIN( "DATE" ), 'YYYY-MM-DD HH24:MI:SS' ) AS shutdown_start,
           TO_CHAR( MAX( "DATE" ), 'YYYY-MM-DD HH24:MI:SS' ) AS shutdown_end,
           TO_CHAR( MAX( "DATE" ) - MIN( "DATE" ) + INTERVAL '5' MINUTE ) AS shutdown_duration
    FROM   grps
    GROUP BY MACHINE_ID, grp
    ORDER BY 1,2
    

    結果

    | MACHINE_ID |      SHUTDOWN_START |        SHUTDOWN_END |             SHUTDOWN_DURATION |
    |------------|---------------------|---------------------|-------------------------------|
    |          1 | 2015-07-07 12:05:00 | 2015-07-07 12:15:00 | +000000000 00:15:00.000000000 |
    |          1 | 2015-07-07 12:35:00 | 2015-07-07 12:50:00 | +000000000 00:20:00.000000000 |
    |          1 | 2015-07-07 13:05:00 | 2015-07-07 13:15:00 | +000000000 00:15:00.000000000 |
    |          2 | 2015-07-07 12:35:00 | 2015-07-07 12:45:00 | +000000000 00:15:00.000000000 |
    |          2 | 2015-07-07 13:00:00 | 2015-07-07 13:15:00 | +000000000 00:20:00.000000000 |
    


    1. Oracleでの日付減算の問題

    2. エラー集計関数を回避する方法はWHEREでは許可されていません

    3. MYSQL重複キーが機能しない

    4. キー値リストに基づいて条件付きでレコードを取得するSQLクエリ