【问题标题】:How do I add a column to identify sequences of dates如何添加列来识别日期序列
【发布时间】:2015-10-27 00:43:52
【问题描述】:

我有很多行约会成员 ID 和约会日期。我正在尝试找到一种粗略识别约会顺序的方法。例如,下面我的用户“A”有五个约会记录。这些似乎是两个约会顺序,一个在 2 月,另一个在 5 月。

| user | date | | A | 02-01-2014| | A | 02-09-2014| | A | 02-20-2014| | A | 05-10-2014| | A | 05-15-2014| | B | 01-05-2015| | B | 01-20-2015|

我试图提出的输出如下。我希望能够选择一些阈值,比如 45 天,在这一点上将开始一个新的序列。例如,用户“A”在 2014 年 5 月 10 日有一个约会,这是该用户几个月来的第一次约会。因此,该约会在附加列中开始一个新序列。最终结果是每个用户都有一组约会,其中有一个额外的列来标识每行属于哪个序列。

| user | date | Sequence | | A | 02-01-2014| 1 | | A | 02-09-2014| 1 | | A | 02-20-2014| 1 | | A | 05-10-2014| 2 | | A | 05-15-2014| 2 | | B | 01-05-2015| 1 | | B | 01-20-2015| 1 |

我似乎无法找到将这种逻辑融入 CASE 语句的方法。我猜想丢失的部分可以参考之前的约会(如果存在的话)。有什么建议吗?谢谢!

【问题讨论】:

    标签: sql sql-server database tsql date


    【解决方案1】:

    如果您将序列定义为以至少 45 天的间隔开始,那么您可以使用窗口函数来执行此操作:

    select a.*, sum(SequenceStart) over (partition by user order by date) as seq
    from (select a.*,
                 (case when date > dateadd(day, 45, lag(date) over (partition by user order by date)) 
                       then 1 else 0 end
                  end) as SequenceStart
          from appointment a
         ) a;
    

    这使用了 SQL Server 2012+ 中的功能。在早期版本中也是可能的。

    【讨论】:

    • 感谢您的回复!不幸的是,我没有提到我使用的是 SQL Server 2008,所以它不喜欢 lag()。但我认为可能还有其他方法可以引用前一行,所以它仍然有帮助。
    【解决方案2】:

    在 MSSQL 2005+ 中,您可以使用DENSE_RANK,如下所示:

    SELECT *,
           DENSE_RANK() OVER(PARTITION BY [user] ORDER BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [date]), 0)) AS [Sequence]
    FROM Your_Table
    

    希望这会有所帮助。

    【讨论】:

    • 如何处理指定的阈值,例如45 天,在间隔开始新序列之前?
    • 你有采样数据和采样结果吗?
    • 除了发布的问题中包含的数据和结果之外,我没有任何示例数据和结果。这还不够吗?
    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 2013-05-02
    • 2019-02-19
    相关资源
    最近更新 更多