【问题标题】:Self-referencing a table for previous record matching user ID自引用表以匹配用户 ID 的先前记录
【发布时间】:2020-09-30 06:17:02
【问题描述】:

我正在尝试找到从 SQL 数据计算周期时间的最简单方法。在数据源中,我有唯一的站 ID、用户 ID 和日期/时间戳,以及他们正在执行的其他数据。

我想要做的是将表连接到自身,以便对于每个日期/时间戳我得到: - 3 分钟内该用户 ID 的最近前一个实例的日期/时间戳或 null - 这两个戳记之间的差异(循环时间 = 记录之间的时间量)

这应该很简单,但我无法绕开它。有什么帮助吗?

【问题讨论】:

  • 样本数据、预期结果以及您所说的“周期时间”都会有所帮助。
  • @GordonLinoff 周期时间已澄清。我会提供样本数据,但它是保密协议。不过,我认为 GMB 明白了
  • 顺便说一句,如果 GMB 的查询返回正确的结果,我的查询也是如此,并且可能更有效:-)
  • @dnoeth 我确实试过你的,但我让它运行了大约 5 分钟,它没有给出响应,甚至没有给出部分行。
  • 好吧,奇怪。那张桌子有多大? OUTER APPLY 版本有多快?

标签: sql sql-server date join window-functions


【解决方案1】:

很遗憾,SQL Server 不支持窗口函数中的日期范围规范。我建议在这里横向加入:

select 
    t.*, 
    t1.timestamp last_timestamp, 
    datediff(second, t1.timestamp, t.timestamp) diff_seconds
from mytable t
outer apply (
    select top(1) t1.*
    from mytable t1
    where 
        t1.user_id = t.user_id 
        and t1.timestamp >= dateadd(minute, -3, t.timestamp)
        and t1.timestamp < t.timestamp
    order by t1.timestamp desc
) t1

子查询在 3 分钟内为同一 user_id 带来最新的行(或空结果集,如果在该时间范围内没有行)。然后,您可以在外部查询中使用该信息来显示相应的timestamp,并计算与当前查询的差异。

【讨论】:

    【解决方案2】:

    简单计算当前时间戳和LAG时间戳的差,如果超过三分钟则返回NULL:

    with cte as
     (
       select 
          t.*
         ,datediff(second, timestamp, lag(timestamp) over (partition by user_id order by timestamp) as diff_seconds
       from mytable as t
     )
    select cte.*
      ,case when diff_seconds <= 180 then diff_seconds end
    from cte
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      相关资源
      最近更新 更多