我正在尝试创建一个 session_id 列,根据是否有 30 分钟的间隙将一堆会话分组到存储桶中...
身份证 | Session_TM |
---|---|
001 | 00:15:12 |
001 | 00:17:17 |
001 | 01:00:00 |
001 | 01:55:00 |
001 | 01:58:22 |
002 | 02:10:10 |
002 | 02:15:12 |
002 | 04:15:01 |
我追求的结果是这样的..
身份证 | Session_TM_Min | Session_TM_Max | 会话_ID |
---|---|---|---|
001 | 00:15:12 | 00:17:17 | 1 |
001 | 01:00:00 | 01:00:00 | 2 |
001 | 01:55:00 | 01:58:00 | 3 |
002 | 02:10:10 | 02:15:12 | 1 |
001 | 04:15:01 | 04:15:01 | 2 |
我已经在 Partition 上尝试过 Row_Number() 但似乎没有什么可以给我带来正确的结果。
任何支持和想法表示赞赏
使用您的示例数据(但将所有时间增加一小时,否则这会导致检查 00:15:12* 之前 30 分钟的内容时出现问题):
create table #sessions
(
ID varchar(3),
Session_TM time
)
insert into #sessions values
('001','01:15:12'),
('001','01:17:17'),
('001','02:00:00'),
('001','02:55:00'),
('001','02:58:22'),
('002','03:10:10'),
('002','03:15:12'),
('002','05:15:01')
您可以使用 CTE 来建立组,然后进行一些分组和窗口函数来返回您想要的输出:
with myGroups as
(
select
*,
count(newGroup) over (order by Session_TM rows unbounded preceding) as groupNum
from
(
select
*,
case when lag(Session_TM,1,'') over (partition by ID order by Session_TM) < dateadd(minute, -30, Session_TM) then 1 end as newGroup
from #sessions
) s
)
select
g.ID,
min(g.Session_TM) as Session_TM_Min,
max(g.Session_TM) as Session_TM_Max,
row_number() over (partition by g.ID order by g.groupNum) as Session_ID
from myGroups g
group by g.ID,
g.groupNum
结果:
身份证 | Session_TM_Min | Session_TM_Max | 会话_ID |
---|---|---|---|
1 | 00:15:12 | 00:17:17 | 1 |
1 | 00:00:00 | 00:00:00 | 2 |
1 | 00:55:00 | 00:58:22 | 3 |
2 | 00:10:10 | 00:15:12 | 1 |
2 | 00:15:01 | 00:15:01 | 2 |
*如果您需要处理午夜 30 分钟内的时间,那么我建议您需要存储日期时间,而不仅仅是时间值。但如果您确实想在没有日期时间的情况下执行此操作,那么您可以添加到 case 语句中,以将 00:30:00 或更早的任何时间明确标记为“新组”。