Sql 根据两个单独的排名/分组将日期段组合在一起

Sql 根据两个单独的排名/分组将日期段组合在一起,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,大家好,很抱歉我的标题措词不当,我不确定如何准确表达我需要的内容。但我会尝试在下面更好地解释: 我的数据集如下所示: DECLARE @TestDATA TABLE (PERSON_ID int, START_DATE date, END_DATE date,SERVICE_RANK int) INSERT INTO @TestDATA VALUES (123, '2018-01-31', '2018-02-14', 7), (123, '2018-03-28', '2018-04-11

大家好,很抱歉我的标题措词不当,我不确定如何准确表达我需要的内容。但我会尝试在下面更好地解释:

我的数据集如下所示:

DECLARE @TestDATA TABLE (PERSON_ID int, START_DATE date, END_DATE date,SERVICE_RANK int)

INSERT INTO @TestDATA 
VALUES 
(123, '2018-01-31', '2018-02-14', 7), 
(123, '2018-03-28', '2018-04-11', 4), 
(123, '2018-04-12', '2018-04-30', 4), 
(123, '2018-05-25', '2018-06-08', 7), 
(123, '2018-06-08', '2018-06-15', 7), 
(123, '2018-06-19', '2018-06-26', 7), 
(123, '2018-06-26', '2018-09-28', 4), 
(123, '2018-10-10', '2018-11-07', 7), 
(123, '2018-11-27', '2018-12-11', 7), 
(123, '2018-12-11', '2018-12-24', 7)
其中显示了每个人的日期范围和“服务等级”(在本例中只有一个人,但数据库中有10个数千人)

对于每个人员id和每个服务级别,我想对日期周期进行分组,以确定他们有多少不同的周期。在上面的例子中,这就是我想要的:

PERSON ID, START_DATE,  END_DATE,  SERVICE_RANK, SERVICE_PERIOD    
    123    2018-01-31   2018-02-14     7             1
    123    2018-03-28   2018-04-11     4             2
    123    2018-04-12   2018-04-30     4             2
    123    2018-05-25   2018-06-08     7             3
    123    2018-06-08   2018-06-15     7             3
    123    2018-06-19   2018-06-26     7             3
    123    2018-06-26   2018-09-28     4             4
    123    2018-10-10   2018-11-07     7             5
    123    2018-11-27   2018-12-11     7             5
    123    2018-12-11   2018-12-24     7             5  
我尝试过行数、秩、密秩,甚至尝试过可怕的光标,但我无法获得任何效果,因为窗口函数将服务秩视为相同的,因此在上面的示例中,当实际上有5个服务秩时,会看到两个服务秩,它们只是共享相同的编号

此外,在数据集中,并非每个人都会从一个服务级别跳到另一个服务级别再跳回来。他们可能从一个到另一个(例如4->7)并停留在那里,或者他们可能在多行上只有一个服务等级


有什么想法吗?

这是一个缺口和孤岛问题。为此,一种方法是
lag()

select t.*,
       sum(case when prev_service_rank = service_rank then 0 else 1 end) over (partition by person_id order by start_date) as service_period
from (select t.*,
             lag(service_rank) over (partition by person_id order by start_date) as prev_service_rank
      from t
     ) t;

非常感谢!我听说过间隙和孤岛问题,甚至尝试过lag()函数,但我忽略了累积和!再次感谢,非常感谢。