sql-server - 在 SQL Server 2012+ 中选择连续时间段的最小开始时间和最大结束时间

标签 sql-server partitioning gaps-and-islands

我在 SQL Server 2012 中有一个表,其事件日志的格式如下:

+=====+=============================+=============================+======+
| ID1 |       start_time_utc        |        end_time_utc         | ID2  |
+=====+=============================+=============================+======+
|  57 | 2018-11-11 11:00:00.0000000 | 2018-11-11 11:00:28.0012900 |   15 |
|  57 | 2018-11-11 11:00:28.0012900 | 2018-11-11 11:01:29.0543947 | 1020 |
|  57 | 2018-11-11 11:01:29.0543947 | 2018-11-11 11:02:28.1923079 |   16 |
|  57 | 2018-11-11 11:02:28.1923079 | 2018-11-11 11:04:28.3367626 |   16 |
|  57 | 2018-11-11 11:04:28.3367626 | 2018-11-11 11:05:28.5307626 | 1020 |
| 103 | 2018-11-10 20:00:00.0000000 | 2018-11-11 03:00:00.0000000 |   15 |
| 103 | 2018-11-11 03:00:00.0000000 | 2018-11-11 10:57:00.8175737 |   15 |
| 103 | 2018-11-11 10:57:00.8175737 | 2018-11-11 10:57:27.8322749 | 1017 |
| 103 | 2018-11-11 10:57:27.8322749 | 2018-11-11 11:00:00.0000000 |   15 |
| 103 | 2018-11-11 11:00:00.0000000 | 2018-11-11 11:00:31.9916890 |   15 |
+-----+-----------------------------+-----------------------------+------+

对于给定的 ID1,结束日期与下一个事件的开始日期相匹配。我想通过匹配 ID1 和 ID2 列来对数据进行分区,并为连续事件的每个分区选择开始日期和结束日期。所以结果应该是:

+=====+=============================+=============================+======+
| ID1 |       start_time_utc        |        end_time_utc         | ID2  |
+=====+=============================+=============================+======+
|  57 | 2018-11-11 11:00:00.0000000 | 2018-11-11 11:00:28.0012900 |   15 |
|  57 | 2018-11-11 11:00:28.0012900 | 2018-11-11 11:01:29.0543947 | 1020 |
|  57 | 2018-11-11 11:01:29.0543947 | 2018-11-11 11:04:28.3367626 |   16 |
|  57 | 2018-11-11 11:04:28.3367626 | 2018-11-11 11:05:28.5307626 | 1020 |
| 103 | 2018-11-10 20:00:00.0000000 | 2018-11-11 10:57:00.8175737 |   15 |
| 103 | 2018-11-11 10:57:00.8175737 | 2018-11-11 10:57:27.8322749 | 1017 |
| 103 | 2018-11-11 10:57:27.8322749 | 2018-11-11 11:00:31.9916890 |   15 |
+-----+-----------------------------+-----------------------------+------+

我显然无法使用简单的分组依据,也不知道如何通过查询写入分区。感谢您的帮助。

最佳答案

这是一个更新版本,适用于给定的数据集,还可以处理在我测试过的所有情况下 id1、id2 序列大于 2 的情况。这比我原来的答案简单得多。将 tstGrouping 替换为您的表名称。

;with p as
(
  select
   ROW_NUMBER () over (order by id1, start_time_utc) as row_num,
   ROW_NUMBER () over (order by id1,id2, start_time_utc) as row_num2,
    *
  from
    tstgrouping x1
)
select 
  id1,
  min(start_time_utc) as start_time_utc,
  max(end_time_utc) as end_time_utc,
  id2
from p
  group by
row_num - row_num2,id1,id2
order by 
id1, start_time_utc

关于sql-server - 在 SQL Server 2012+ 中选择连续时间段的最小开始时间和最大结束时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53272295/

相关文章:

kubernetes - Kubernetes 中有状态服务的分片负载均衡

sql - 卡在涉及时间段的 Gaps and Islands 查询上

sql - 根据两个单独的排名/分组将日期时间段分组在一起

sql-server - 将 ssis 表达式日期时间转换为 int

c# - 将 Int 参数从 C# 发送到存储过程

debian - 划分专用服务器硬盘是否有意义?

mysql - 如果 MySQL 上不存在则创建分区

sql - 如何从一系列数字中检查任何缺失的数字?

mysql - 在 mysql 表中查找 id 不唯一的漏洞

sql-server - 从 SQL Server 2005 存储过程进行 FTP 的最佳实践是什么?