繁体   English   中英

SQL:通过多次迭代获取最小值和最大值

[英]SQL : Get min and max with multiple iterations

我试图在 MSSQL 中为这个示例表获取按 activityid、dateid 和 personid 分组的最小开始和最大停止。

源表如下所示:

+--------+--------+------------------+------------------+------------+
| USERID | DATEID |      START       |       END        | ACTIVITYID |
+--------+--------+------------------+------------------+------------+
|      1 |      1 | 11/01/2021 12:10 | 11/01/2021 12:15 | A          |
|      1 |      1 | 11/01/2021 12:15 | 11/01/2021 12:30 | A          |
|      1 |      1 | 11/01/2021 12:30 | 11/01/2021 12:45 | A          |
|      1 |      1 | 11/01/2021 12:45 | 11/01/2021 13:00 | A          |
|      1 |      1 | 11/01/2021 13:00 | 11/01/2021 13:15 | A          |
|      1 |      1 | 11/01/2021 13:15 | 11/01/2021 13:30 | A          |
|      1 |      1 | 11/01/2021 13:30 | 11/01/2021 13:45 | A          |
|      1 |      1 | 11/01/2021 13:45 | 11/01/2021 13:55 | A          |
|      1 |      1 | 11/01/2021 13:55 | 11/01/2021 14:00 | B          |
|      1 |      1 | 11/01/2021 14:00 | 11/01/2021 14:05 | B          |
|      1 |      1 | 11/01/2021 14:05 | 11/01/2021 14:15 | A          |
|      1 |      1 | 11/01/2021 14:15 | 11/01/2021 14:30 | A          |
|      1 |      1 | 11/01/2021 14:30 | 11/01/2021 14:45 | A          |
|      1 |      1 | 11/01/2021 14:45 | 11/01/2021 15:00 | A          |
|      1 |      1 | 11/01/2021 15:00 | 11/01/2021 15:10 | A          |
|      1 |      1 | 11/01/2021 15:10 | 11/01/2021 15:15 | C          |
|      1 |      1 | 11/01/2021 15:15 | 11/01/2021 15:30 | C          |
|      1 |      1 | 11/01/2021 15:30 | 11/01/2021 15:45 | C          |
|      1 |      1 | 11/01/2021 15:45 | 11/01/2021 16:00 | C          |
|      1 |      1 | 11/01/2021 16:00 | 11/01/2021 16:10 | C          |
|      1 |      1 | 11/01/2021 16:10 | 11/01/2021 16:15 | A          |
|      1 |      1 | 11/01/2021 16:15 | 11/01/2021 16:30 | A          |
|      1 |      1 | 11/01/2021 16:30 | 11/01/2021 16:45 | A          |
|      1 |      1 | 11/01/2021 16:45 | 11/01/2021 17:00 | A          |
|      1 |      1 | 11/01/2021 17:00 | 11/01/2021 17:15 | A          |
|      1 |      1 | 11/01/2021 17:15 | 11/01/2021 17:30 | A          |
|      1 |      1 | 11/01/2021 17:30 | 11/01/2021 17:45 | A          |
|      1 |      1 | 11/01/2021 17:45 | 11/01/2021 18:00 | A          |
|      1 |      1 | 11/01/2021 18:00 | 11/01/2021 18:15 | A          |
|      1 |      1 | 11/01/2021 18:15 | 11/01/2021 18:30 | A          |
|      1 |      1 | 11/01/2021 18:30 | 11/01/2021 18:40 | A          |
|      1 |      1 | 11/01/2021 18:40 | 11/01/2021 18:45 | B          |
|      1 |      1 | 11/01/2021 18:45 | 11/01/2021 18:50 | B          |
|      1 |      1 | 11/01/2021 18:50 | 11/01/2021 19:00 | A          |
|      1 |      1 | 11/01/2021 19:00 | 11/01/2021 19:15 | A          |
|      1 |      1 | 11/01/2021 19:15 | 11/01/2021 19:30 | A          |
|      1 |      1 | 11/01/2021 19:30 | 11/01/2021 19:45 | A          |
|      1 |      1 | 11/01/2021 19:45 | 11/01/2021 20:00 | A          |
|      1 |      1 | 11/01/2021 20:00 | 11/01/2021 20:15 | A          |
|      1 |      1 | 11/01/2021 20:15 | 11/01/2021 20:30 | A          |
|      1 |      1 | 11/01/2021 20:30 | 11/01/2021 20:45 | A          |
|      1 |      1 | 11/01/2021 20:45 | 11/01/2021 21:00 | A          |
+--------+--------+------------------+------------------+------------+

最后的结果应该是这样的:

+--------+--------+------------------+------------------+------------+
| USERID | DATEID |      START       |       END        | ACTIVITYID |
+--------+--------+------------------+------------------+------------+
|      1 |      1 | 11/01/2021 12:10 | 11/01/2021 13:55 | A          |
|      1 |      1 | 11/01/2021 13:55 | 11/01/2021 14:05 | B          |
|      1 |      1 | 11/01/2021 14:05 | 11/01/2021 15:10 | A          |
|      1 |      1 | 11/01/2021 15:10 | 11/01/2021 16:10 | C          |
|      1 |      1 | 11/01/2021 16:10 | 11/01/2021 18:40 | A          |
|      1 |      1 | 11/01/2021 18:40 | 11/01/2021 18:50 | B          |
|      1 |      1 | 11/01/2021 18:50 | 11/01/2021 21:00 | A          |
+--------+--------+------------------+------------------+------------+

我试过使用上一行/下一行的值,但它只会返回上一行,但是无法获得第一行和最后一行。

谢谢您的帮助!

这是一种间隙和孤岛问题。 假设相邻的值没有间隙,那么行号的差异是最简单的做法:

select userid, dateid, activityid,
       min(start), max(end)
from (select t.*,
             row_number() over (partition by userid, dateid order by start) as seqnum,
             row_number() over (partition by userid, dateid, activity_id order by start) as seqnum_2
      from t
     ) t
group by userid, dateid, activityid, (seqnum - seqnum_2)
order by userid, dateid, min(start);

请注意, startend对于列名来说是非常糟糕的选择,因为它们是 SQL 关键字。 我假设你的真实姓名更安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM