从 Oracle 12 开始,您可以使用MATCH_RECOGNIZE
:
SELECT *
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY userid
ORDER BY date_time_stamp
MEASURES
FIRST(taskid) AS taskid,
FIRST(date_time_stamp) AS start_date,
LAST(date_time_stamp) AS end_date
ONE ROW PER MATCH
PATTERN ( same_task+ )
DEFINE same_task AS FIRST(taskid) = taskid
)
在此之前,您可以使用ROW_NUMBER
分析函数和聚合:
SELECT userid,
taskid,
MIN(date_time_stamp) AS start_date,
MAX(date_time_stamp) AS end_date
FROM (
SELECT t.*,
ROW_NUMBER() OVER ( PARTITION BY userid ORDER BY date_time_stamp )
- ROW_NUMBER() OVER ( PARTITION BY userid, taskid ORDER BY date_time_stamp )
AS grp
FROM table_name t
)
GROUP BY userid, taskid, grp
ORDER BY userid, start_date
其中,对于您的示例数据:
CREATE TABLE table_name ( userid, taskid, date_time_stamp ) AS
SELECT 1, 'task-A', DATE '2021-06-16' + INTERVAL '04:17:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-A', DATE '2021-06-16' + INTERVAL '04:19:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-A', DATE '2021-06-16' + INTERVAL '04:27:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-B', DATE '2021-06-16' + INTERVAL '04:31:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-B', DATE '2021-06-16' + INTERVAL '04:33:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-B', DATE '2021-06-16' + INTERVAL '04:36:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-A', DATE '2021-06-16' + INTERVAL '04:42:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 1, 'task-A', DATE '2021-06-16' + INTERVAL '04:44:00' HOUR TO SECOND FROM DUAL
两个输出:
用户身份 |
任务ID |
开始日期 |
结束日期 |
1 |
任务-A |
2021-06-16 04:17:00 |
2021-06-16 04:27:00 |
1 |
任务-B |
2021-06-16 04:31:00 |
2021-06-16 04:36:00 |
1 |
任务-A |
2021-06-16 04:42:00 |
2021-06-16 04:44:00 |
db<>在这里摆弄