Tsql 按序列对事件分组,定义序列之间的最短周期t-SQL

Tsql 按序列对事件分组,定义序列之间的最短周期t-SQL,tsql,Tsql,我有一个名为tbl_events的事件表,看起来像这样: PersonID Date 1 30/03/2015 1 22/04/2015 1 30/06/2015 2 18/07/2016 2 09/12/2016 2 28/04/2017 3 01/10/2014 3 28/11/2016 3 28/11/20

我有一个名为
tbl_events
的事件表,看起来像这样:

PersonID    Date
1           30/03/2015
1           22/04/2015
1           30/06/2015
2           18/07/2016
2           09/12/2016
2           28/04/2017
3           01/10/2014
3           28/11/2016
3           28/11/2016
3           16/01/2017
4           13/04/2017
4           09/05/2017
我希望能够根据每个“序列”的开始日期对这些事件进行分组,序列被定义为每个PersonID从第一次识别到最后一次识别的事件运行。序列中的最后一个事件被定义为此后一年内该人员没有后续事件的事件

我希望其结果如下所示:

PersonID    FirstDate   Sequence    Events
1           30/03/2015  1           3
2           18/07/2016  1           3
3           01/10/2014  1           1
3           28/11/2016  2           3
4           13/04/2017  1           2
我能够在Excel中识别序列并透视数据,但我需要能够在SQL中做到这一点

以下是我在Excel中用于生成序列号的公式(我正在填充单元格C3,A列为PersonID,B列为Date):


=+IF(A2A3,1,IF((B3-B2)我的解决方案基于您随excel公式提供的示例数据

-- easily consumable sample data
DECLARE @tbl_events TABLE (PersonId int, [date] date)
INSERT @tbl_events VALUES
(1,'20150330'),(1,'20150422'),(1,'20150630'),(2,'20160718'),(2,'20161209'),(2,'20170428'),
(3,'20141001'),(3,'20161128'),(3,'20161128'),(3,'20170116'),(4,'20170413'),(4,'20170509');

-- Solution
WITH groupings AS
(
  SELECT 
    PersonId, 
    FirstDate = MIN([date]) OVER (PARTITION BY personId ORDER BY [date]),
    NextDate  = LAG([date],1,[date]) OVER (PARTITION BY personId ORDER BY [date]),
    [date],
    grouper   = 
      DATEDIFF(DAY, MIN([date]) OVER (PARTITION BY personId ORDER BY [date]), [date]) / 365
  FROM @tbl_events
),
Prep AS
(
  SELECT 
    PersonId, 
    firstDate = IIF(grouper = 0, FirstDate, IIF(FirstDate = NextDate, [date],NextDate))
  FROM groupings
)
SELECT 
  PersonId, 
  FirstDate, 
  [Sequence] = ROW_NUMBER() OVER (PARTITION BY personId ORDER BY FirstDate),
  [Events] = COUNT(*)
FROM prep
GROUP BY personId, FirstDate;
结果

PersonId    FirstDate  Sequence             Events
----------- ---------- -------------------- -----------
1           2015-03-30 1                    3
2           2016-07-18 1                    3
3           2014-10-01 1                    1
3           2016-11-28 2                    3
4           2017-04-13 1                    2
第一个注意:所有年份都有365天,尽管如此,我使用365来模拟您的excel逻辑;这需要更新以说明闰年。接下来,就像您的excel公式一样,只有当有两个序列时,这才是正确的; 假设personId的日期为2015年1月1日、2016年1月10日、2017年2月1日,那么它将不起作用。请告知我们是否需要逻辑来适应上述场景


最后,此解决方案使用LAG,这需要SQL Server 2012+,如果您使用的是早期版本的SQL,则必须相应地更新查询。

您使用的是哪个版本的SQL Server?SQL Server 2008谢谢Alan,这看起来很有希望,尽管da中肯定会有超过2个序列的PersonIDta.我提供的Excel公式目前有效——如果两个事件之间的时间间隔超过365天(我不担心闰年),它会在之前的序列号上加1,因此每个PersonID的序列号没有限制。我使用的是SQL Server 2008。
PersonId    FirstDate  Sequence             Events
----------- ---------- -------------------- -----------
1           2015-03-30 1                    3
2           2016-07-18 1                    3
3           2014-10-01 1                    1
3           2016-11-28 2                    3
4           2017-04-13 1                    2