在SQL Server中计算多行数据的用户总暂停时长
没问题,我来帮你实现这个用户暂停时长的统计需求!先把你的原始数据整理成清晰的表格:
| ID | UserId | Event | Date |
|---|---|---|---|
| 1 | 123 | Start | 11/07/2017 14:00:00 |
| 2 | 123 | PauseStart | 11/07/2017 14:52:52 |
| 3 | 123 | PauseEnd | 11/07/2017 14:56:03 |
| 4 | 123 | PauseStart | 11/07/2017 15:39:45 |
| 5 | 123 | PauseEnd | 11/07/2017 15:45:10 |
| 6 | 123 | Finish | 11/07/2017 17:45:15 |
| 7 | 124 | Start | 11/07/2017 18:00:00 |
| 8 | 124 | PauseStart | 11/07/2017 19:52:52 |
| 9 | 124 | PauseEnd | 11/07/2017 20:05:03 |
| 10 | 124 | Finish | 11/07/2017 20:45:15 |
要统计每个用户的总暂停时长,核心是把每一对PauseStart和对应的PauseEnd准确配对,计算单次暂停的秒数后求和。这里用窗口函数+自连接的方式就能完美解决,直接看SQL代码:
-- 先给每个用户的暂停事件按顺序编号,方便配对 WITH numbered_pauses AS ( SELECT UserId, Event, Date, -- 给每个用户的PauseStart和PauseEnd分别按时间排序编号 ROW_NUMBER() OVER (PARTITION BY UserId, Event ORDER BY Date) AS pause_seq FROM your_event_table WHERE Event IN ('PauseStart', 'PauseEnd') -- 只保留暂停相关事件 ) -- 配对PauseStart和对应的PauseEnd,计算总时长 SELECT ps.UserId, SUM(TIMESTAMPDIFF(SECOND, ps.Date, pe.Date)) AS `TotalPauses(seconds)` FROM numbered_pauses ps INNER JOIN numbered_pauses pe ON ps.UserId = pe.UserId AND ps.pause_seq = pe.pause_seq AND ps.Event = 'PauseStart' AND pe.Event = 'PauseEnd' GROUP BY ps.UserId;
代码逻辑说明:
- 筛选并编号暂停事件:通过CTE
numbered_pauses提取所有和暂停相关的事件,同时给每个用户的PauseStart和PauseEnd分别按时间顺序分配序号(比如用户123的两次PauseStart会被编号为1、2,对应的PauseEnd也会是1、2); - 配对计算单次时长:将
PauseStart行和同用户、同序号的PauseEnd行连接,用TIMESTAMPDIFF函数计算单次暂停的秒数; - 分组求和:按用户ID分组,把所有单次暂停时长加总,得到每个用户的总暂停时长。
运行这段代码后,就能得到你期望的结果:
| UserID | TotalPauses(seconds) |
|---|---|
| 123 | 720 |
| 124 | 840 |
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

