Oracle SQL如何分组连续相同任务并获取每次变更的最早时间
解决方案:连续相同Task分组并获取首次出现时间
针对连续相同Task的分组需求,单独用DENSE_RANK()或ROW_NUMBER()无法区分连续的同组记录,这里用行号差值法可以解决问题,核心是通过两个行号的差值标记连续同组的记录。
示例数据(已按Time排序)
| Time | Task |
|---|---|
| 2024-01-01 08:00:00 | TaskA |
| 2024-01-01 08:10:00 | TaskA |
| 2024-01-01 08:20:00 | TaskB |
| 2024-01-01 08:30:00 | TaskB |
| 2024-01-01 08:40:00 | TaskA |
实现SQL
WITH grouped_tasks AS ( SELECT Time, Task, -- 按Time全局排序的行号 ROW_NUMBER() OVER (ORDER BY Time) AS global_row, -- 按Task分组、Time排序的行号 ROW_NUMBER() OVER (PARTITION BY Task ORDER BY Time) AS task_row FROM your_table_name -- 替换为你的表名 ) SELECT Task, MIN(Time) AS first_time_of_group FROM grouped_tasks -- 差值相同的记录属于连续同组 GROUP BY Task, (global_row - task_row) ORDER BY first_time_of_group;
原理说明
global_row是全表按Time排序的行号,保证顺序和原表一致;task_row是每个Task分组内按Time排序的行号;global_row - task_row会为连续相同的Task生成相同的分组标识:比如示例中前两条TaskA的差值为0,属于同一组;中间两条TaskB差值为2,属于同一组;最后一条TaskA差值为2,和之前的TaskA组差值不同,是新的独立组。- 分组后取
MIN(Time)即可得到每个连续Task组的最早时间,也就是任务变更时的首次出现时间。
该方法适用于所有支持窗口函数的数据库(如MySQL 8+、PostgreSQL、SQL Server等)。
内容的提问来源于stack exchange,提问作者Avia Portal
相关产品推荐
相关产品推荐

