SQL 总结时间范围内的最小/最大事件

标签 sql

这是一个 SQL 问题,我无法通过简单的查询解决这个问题,这可能吗?

数据集是(为了便于理解而添加的字母):

Start      End
10:01      10:12     (A)
10:03      10:06     (B)
10:05      10:25     (C)
10:14      10:42     (D)
10:32      10:36     (E)

所需的输出是:

PeriodStart   New       ActiveAtEnd    MinActive   MaxActive
09:50         0         0              0           0
10:00         3 (ABC)   2 (AC)         0           3 (ABC)
10:10         1 (D)     2 (CD)         1 (C)       2 (AC or CD)
10:20         0         1 (D)          1 (C)       2 (CD)
10:30         1 (E)     1 (D)          1 (D)       2 (DE)
10:40         0         0              0           1 (D)
10:50         0         0              0           0

因此,需要的查询是第一个表的摘要,计算 10 分钟内与第一个表的最小重叠时间段(Start-End)和最大重叠时间段(Start-End)。

"new"是汇总期间中带有“开始”的行数。 “ActiveAtEnd”是汇总周期结束时事件的行数。

我正在使用 Oracle,但我确信可以调整解决方案。不允许存储过程 - 只是简单的 SELECT/INSERT(允许 View )。每 10 分钟输出运行一个 SQL 命令也是可以的(一旦填充,这将是它保持最新的方式。

感谢您的任何想法,包括“不可能”;-)

最佳答案

假设您还有(或创建)一个名为 @Times 的表,其中每十分钟开始时间有一条记录, 怎么样...

   Select T.Start,  
      (Select Count(*) From testTab
       Where Start Between T.Start 
          And DateAdd(minute, 10, T.Start)) New,
      (Select Count(*) From testTab
       Where Start < DateAdd(minute, 10, T.Start)
          And EndDt > DateAdd(minute, 10, T.Start)) ActiveAtEnd,
      (Select Max(Cnt) From 
          (Select Count(Distinct T.Which) Cnt
           From  (Select Distinct Start
                    From testTab
                    Where Start Between T.Start 
                           And DateAdd(minute, 10, T.Start)
                    Union Select T.Start 
                    Union Select DateAdd(minute, 10, T.Start)) Z
             Left Join testTab T 
               On Z.Start Between T.Start And T.EndDt
           Group By Z.Start) ZZ ) MaxActive,
      (Select Min(Cnt) From 
           (Select Count(Distinct T.Which) Cnt
            From  (Select Distinct Start
                   From testTab
                   Where Start Between T.Start 
                           And DateAdd(minute, 10, T.Start)
                   Union Select T.Start                                                         
                   Union Select DateAdd(minute, 10, T.Start)) Z
              Left Join testTab T 
                 On Z.Start Between T.Start And T.EndDt
           Group By Z.Start) ZZ ) MinActive     
   From @Times T

我在 SQL Server 中创建了此表作为表变量,使用

Declare @Times Table (Start datetime Primary key Not Null)
Declare @Start DateTime 
Set @Start = '1 Nov 2008 10:00'
While @Start < '1 Nov 2008 11:00' begin
    Insert @Times(Start) values(@Start)
    Set @Start = DateAdd(minute, 10, @Start) 
End

如果您使用的是其他产品,请使用临时表...但这种方法确实需要一个每十分钟“时间段”有一条记录的表作为运行的钩子(Hook)...

使用以下数据,此查询将生成如下输出:

start                   endDt                   Which
----------------------- ----------------------- -----
2008-11-01 10:01:00.000 2008-11-01 10:12:00.000 A
2008-11-01 10:03:00.000 2008-11-01 10:06:00.000 B
2008-11-01 10:05:00.000 2008-11-01 10:25:00.000 C
2008-11-01 10:14:00.000 2008-11-01 10:42:00.000 D
2008-11-01 10:32:00.000 2008-11-01 10:36:00.000 E
2008-11-01 10:22:00.000 2008-11-01 10:51:00.000 F
2008-11-01 10:22:00.000 2008-11-01 10:23:00.000 G

Start                   New         ActiveAtEnd MaxActive   MinActive
----------------------- ----------- ----------- ----------- -----------
2008-11-01 10:00:00.000 3           2           3           0
2008-11-01 10:10:00.000 1           2           2           2
2008-11-01 10:20:00.000 2           2           4           2
2008-11-01 10:30:00.000 1           2           3           2
2008-11-01 10:40:00.000 0           1           2           1
2008-11-01 10:50:00.000 0           0           1           0

警告:空值会被聚合或其他 SET 操作消除。

关于SQL 总结时间范围内的最小/最大事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/301695/

相关文章:

mysql - 选择具有一个最大日期的两个不同列

sql - 从当前 sysdate 中检索最近两年的数据

SQL 2005/8 异常更新 "black arts"

sql - 在 postgresql 中生成自动 ID

MySQL : can't figure out what's wrong with this LEFT JOIN query

mysql - SQL Server 如何创建带空格的列名

SQL Server 使用分隔符拆分字符串

sql - 如何在 MSSQL 中的 VARCHAR 列上创建 CHECK 约束,指定数据中可能出现的有效字符集?

sql - 获得薪资第三高的员工

sql - 在 PostgreSQL 中调整查询