【问题标题】:(T-SQL) Sum datetime value gaps based on where clause(T-SQL) 根据 where 子句求和日期时间值的差距
【发布时间】:2017-07-31 10:06:29
【问题描述】:

需要帮助编写一个查询,该查询将基于另一列汇总日期时间字段中的时间值。让我解释一下:

假设我有一个表 Table1 有 2 个字段:timeStamp DATETIME 类型和 player VARCHAR。假设我在球员 A 拿到球时输入了一个时间戳,一段时间后球员 B 拿到球,我输入了他的时间,所以最终我会得到这样的结果:

+-------------------------+---------+
|        TimeLapse        | Player  |
+-------------------------+---------+
| 2017-07-03 10:37:14.740 | playerA |
| 2017-07-03 11:49:14.787 | playerB |
| 2017-07-03 11:53:59.157 | playerA |
| 2017-07-03 12:58:30.313 | playerA |
| 2017-07-03 12:58:34.000 | playerB |
| 2017-07-03 13:58:43.327 | playerA |
| 2017-07-04 19:48:39.817 | playerA |
| 2017-07-05 11:54:53.657 | playerA |
+-------------------------+---------+

我最终想要的是计算球员A拿到球的时间(比如说以分钟为单位)(只有当他拿到球时)。 我有点卡住了。我可以毫无问题地得到 playerA 持球的所有时间,但后来我不知何故需要减去 playerB 持球的时间。 所以我需要总结一下:

time from
 | 2017-07-03 10:37:14.740 | playerA |
to
 | 2017-07-03 11:49:14.787 | playerB |
then from
 | 2017-07-03 11:53:59.157 | playerA |
to
 | 2017-07-03 12:58:30.313 | playerA |
and to
 | 2017-07-03 12:58:34.000 | playerB |
...
and so on

有人可以提出一个策略,或者展示它是如何完成的吗? 谢谢。

【问题讨论】:

  • playerA如何将球传给自己?确定该记录不应该存在吗?
  • 感谢您指出这一点。但这只是我的愚蠢例子。我可能应该再举一个例子,但是这个记录是可能的。假设他有球,然后丢球,然后又得到了!丢球的时间并不重要。
  • 所以你想总结的差距是玩家和自己之间的差距,以及玩家和其他人之间的差距。
  • 是的。你是对的

标签: sql sql-server tsql datetime


【解决方案1】:

您可以使用行号差异方法来识别组。然后您可以使用聚合和lead() 来获取开始和结束时间,如下所示:

select player, min(timelapse) as start_timelapse, 
       lead(max(timelapse)) over (order by max(timelapse)
                                 ) as next_timelapse
from (select t1.*,
             row_number() over (order by timelapse) as seqnum_t,
             row_number() over (partition by player order by timelapse) as seqnum_tp
      from table1 t1
     ) t1
group by (seqnum_t - seqnum_tp), player;

这是如何工作的有点棘手。运行子查询以找出为什么两个行号的差异标识了您想要的组。

对于时差,您希望使用返回的两列。目前尚不清楚您想要什么单位,但datediff() 将是典型的方法。

【讨论】:

  • 谢谢!看起来像我需要的。我自己也在考虑LAG(),但还没有一个完整的想法。我唯一不明白的是lag(max(timelapse)) over (partition by player, (seqnum_t - seqnum_tp) order by max(timelapse) as next_timelaps 我需要使用 datediff 代替 (seqnum_t - seqnum_tp) 来获得与 start_ 和 laagged_ 的区别吗?
  • @JohnDoe 。 . .糟糕,应该是lead(),而不是lag(),因为你想要下一个。
  • 是的,是的)我得到了。不过,LEADLAG 给了我 NULL。我不明白为什么。子查询运行良好,我看到 seqnum_t 和 _tp 的等级数。但是over (partition by player, (seqnum_t - seqnum_tp) order by max(timelapse) next_timelapse 为 NULL
  • @JohnDoe 。 . .对于lead(),我们不想按 player 或 grp 进行分区。 . .我们只想要下一个。
  • 太棒了!谢谢戈登·林诺夫。需要花更多时间学习LAGLEAD
猜你喜欢
  • 2023-03-21
  • 2011-07-13
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2023-03-04
相关资源
最近更新 更多