Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Grupowanie SQL na interwale czasowym

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;

Wyjście:

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  

Edytuj – wiele komputerów:

Skrzypce SQL

Konfiguracja schematu Oracle 11g R2 :

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;

Zapytanie 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

Wyniki :

| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle, PDO_OCI a OCI8

  2. Jak połączyć się z serwerem LDAP za pomocą node-oracledb?

  3. 19.3 PDB Zamknij ORA-65107 ORA-16078

  4. Wiersz dla każdej daty od daty rozpoczęcia do daty zakończenia

  5. Jak wstawić wartość tożsamości w Oracle przy użyciu Entity Framework przy użyciu sekwencji