我有一个基于时间戳的数据集。数据集在5分钟的时间间隔内记录每次关闭事件。如果在特定的5分钟内发生关闭,则添加记录,否则不记录。因此,没有记录意味着系统已经恢复
Date
07-Jul-15 12:05:00
07-Jul-15 12:10:00
07-Jul-15 12:15:00
07-Jul-15 12:35:00
07-Jul-15 12:40:00
07-Jul-15 12:45:00
07-Jul-15 12:50:00
07-Jul-15 13:05:00
07-Jul-15 13:10:00
07-Jul-15 13:15:00
我想查询并返回
1.关闭次数:在这种情况下,关闭次数为3,基于
12:15 to 12:35 12:50 to 13:05
系统已恢复
- 每次关闭之间的时间段
醇>示例:
1.From:07-Jul-15 12:05:00 To:07-Jul-15 12:15:00持续时间:15分钟
2.From:07-Jul-15 12:35:00 To:07-Jul-15 12:50:00持续时间:20分钟
有similar个问题,但这个问题需要一个非常不同的解决方案。
会欣赏一个小提琴的例子
答案 0 :(得分:1)
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
编辑 - 多台计算机:
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;
查询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
<强> Results 强>:
| 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 :(得分:0)
解决方案使用Tom Kyte&#34;&#34;结束&#34;技术:
with test1 as (
select mydate,
-- mark starting records in each group
case when NVL((mydate - lag(mydate) over (order by mydate))*24*60,10) > 5
then row_number() over (order by mydate) end as group_id
from test),
test2 as (
select mydate,
-- propagate group_id to all records
LAST_VALUE(group_id IGNORE NULLS) over (order by mydate) as group_id
from test1)
select min(mydate) shutdown_from, max(mydate) shutdown_to
from test2
group by group_id;
<强>输出强>
SHUTDOWN_FROM SHUTDOWN_TO
------------------- -------------------
07.07.0015 12:05:00 07.07.0015 12:15:00
07.07.0015 12:35:00 07.07.0015 12:50:00
07.07.0015 13:05:00 07.07.0015 13:15:00