【问题标题】:T-SQL filtering records based on dates and time difference with other recordsT-SQL 根据与其他记录的日期和时间差过滤记录
【发布时间】:2021-03-12 17:18:33
【问题描述】:

我有一张表,我必须对其执行相当复杂的过滤:首先应用按日期过滤,但如果前几天和后几天的记录与其时差不超过 8 小时,则应包括在内上一条或下一条记录(取决于日期是小于还是大于过滤日期)。

对于那些相邻的日子,选择应该在不满足此条件的第一条记录处停止。

这是我的原始数据的样子:

Id Desc EntryDate
1 Event type 1 2021-03-12 21:55:00.000
2 Event type 1 2021-03-12 01:10:00.000
3 Event type 1 2021-03-11 20:17:00.000
4 Event type 1 2021-03-11 05:04:00.000
5 Event type 1 2021-03-10 23:58:00.000
6 Event type 1 2021-03-10 11:01:00.000
7 Event type 1 2021-03-10 10:00:00.000

在这个示例集中,如果我的过滤日期是“2021-03-11”,我的预期结果集应该是当天的所有记录加上满足 8 小时条件的 03-12 和 03-10 的相邻记录。请注意如何不包含 ID 为 7 的记录,因为 ID 为 6 的记录不符合要求:

Id EntryDate
2 2021-03-12 01:10:00.000
3 2021-03-11 20:17:00.000
4 2021-03-11 05:04:00.000
5 2021-03-10 23:58:00.000

需要建议如何编写这个复杂的查询

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    这是间隙和岛屿的变体。定义差异。 . .然后根据差异进行分组:

    with e as (
          select t.*
          from (select t.*,
                       sum(case when prev_entrydate > dateadd(hour, -8, entrydate) then 0 else 1 end) over (order by entrydate) as grp
                from (select t.*,
                             lag(entrydate) over (order by entrydate) as prev_entrydate
                      from t
                     ) t
         )
    select e.*
    from e.*
    where e.grp in (select e2.grp
                    from t e2
                    where date(e2.entrydate) = @filterdate
                   );
    

    注意:我不确定过滤器日期是如何应用的。这假设它是一整天的任何事件,这意味着可能有多个组。如果只有一个组(比如当天的第一组),从性能的角度来看,查询可以简化一点。

    【讨论】:

    • 这正是我所追求的!至于事件,一次只请求一个事件,为了清楚起见,我把那部分省略了。
    【解决方案2】:
    declare @DateTime datetime = '2021-03-11'
    
    select *
    from t
    where t.EntryDate between DATEADD(hour , -8 , @DateTime) and DATEADD(hour , 32 , @DateTime)
    

    【讨论】:

      猜你喜欢
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多