如何检测SQ​​L查询中的密钥更改?

时间:2017-05-05 17:11:56

标签: sql sql-server

如何编写一个查询,将组编号分配给共享相同键值的相邻行?我不能使用简单的GROUP BY,因为密钥可以在结果集中不同位置的多个集合中使用。

例如,假设我想压缩这些行,以便可以将相邻时间段的相邻注册记录压缩为单个注册记录。

这里有一些测试数据......

declare @enrollments table (
[Id] int not null identity(1,1),
[PlanCode] nvarchar(10) not null,       -- For simplicity, this is the key.
[BeginDate] int not null,
[EndDate] int null );

insert into @enrollments (PlanCode, BeginDate, EndDate) values 
     ('81-3', 20160101, null)
    ,('80-3', 20150701, 20160101)
    ,('80-3', 20150301, 20150701)
    ,('80-3', 20150101, 20150301)
    ,('80-1', 20140517, 20150101)
    ,('80-3', 20120906, 20140517)
    ,('80-1', 20120101, 20120906);

-- Source data.
select  *
from    @enrollments 
order by BeginDate desc;

-- Goal results.
select [Id] = 1, [PlanCode] = '81-3', [BeginDate] = 20160101, [EndDate] = NULL, [GroupNum] = 1
union
select [Id] = 2, [PlanCode] = '80-3', [BeginDate] = 20150701, [EndDate] = 20160101, [GroupNum] = 2
union
select [Id] = 3, [PlanCode] = '80-3', [BeginDate] = 20150301, [EndDate] = 20150701, [GroupNum] = 2
union
select [Id] = 4, [PlanCode] = '80-3', [BeginDate] = 20150101, [EndDate] = 20150301, [GroupNum] = 2
union
select [Id] = 5, [PlanCode] = '80-1', [BeginDate] = 20140517, [EndDate] = 20150101, [GroupNum] = 3
union
select [Id] = 6, [PlanCode] = '80-3', [BeginDate] = 20120906, [EndDate] = 20140517, [GroupNum] = 4
union
select [Id] = 7, [PlanCode] = '80-1', [BeginDate] = 20120101, [EndDate] = 20120906, [GroupNum] = 5;

所以,提供这些数据......

enter image description here

在最简单的形式中,我基本上需要弄清楚如何确定GroupNum。一旦我有了,我可以GROUP BY并获得我需要的其他聚合。

enter image description here

这意味着"正常"分组不起作用。我真的希望有一种方法可以使用游标循环来解决这个问题。我已经在这几天敲打了我的脑袋。是时候给朋友打电话了!

谢谢! 伊恩

0 个答案:

没有答案