【问题标题】:Identify sub-set of records based on date and rules in SQL Server根据 SQL Server 中的日期和规则识别记录子集
【发布时间】:2016-10-17 20:42:39
【问题描述】:

我有一个如下所示的数据集:

我需要识别 Linked 设置为 1 的行,但仅在按 ToDate 降序排序时它们在一起的位置,如图所示。

换句话说,我希望能够识别这些记录(EDITED):

这是一个简化的数据集,实际上会有更多的记录...

定义记录是否链接的逻辑是记录的 FromDate 是否在前一个日期的 ToDate 的 8 周内...但这是testData 所以可能并不完美

请问最好的方法是什么?

【问题讨论】:

    标签: sql-server tsql select sql-server-2012


    【解决方案1】:

    您可以使用LAG()LEAD() 解析函数:

    SELECT * FROM (
        SELECT t.*,
               LAG(t.linked,1,0) OVER(ORDER BY t.FromDate DESC) as rnk_1, --Next one
               LEAD(t.linked,1,0) OVER(ORDER BY t.FromDate DESC) as rnk_2, -- Last one,
               LEAD(t.linked,2,0) OVER(ORDER BY t.FromDate DESC) as rnk_3 -- Last two,
        FROM YourTable t) s
    WHERE ((s.rnk_1 = 1 OR s.rnk_2 = 1) AND s.linked = 1) OR 
          (s.rnk_2 = 1 and s.rnk_3 = 1 and s.linked = 0)
    ORDER BY s.FromDate DESC
    

    这将导致记录具有linked = 1,并且上一条/下一条记录也是 1。

    【讨论】:

    • 感谢您的回答 - 快速提问 - 不应该是 ORDER BY s.FromDate DESC 吗?
    • 哦,没看到:P 是的 @OurManInBananas
    • 我不得不尝试另一种方式,因为这种方式不包括最近一组链接记录之前带有Linked=0的行
    • 我已经编辑了我的问题,我的同事澄清说我们需要包含Linked=0的行
    • @OurManInBananas 立即尝试
    【解决方案2】:

    使用LAGLEAD 函数,您可以在给定排序条件的情况下检查上一行/下一行的值。

    您可以使用以下 DDL 实现所需的数据集:

    ;
    WITH    CTE_LagLead
              AS (
                  SELECT    FromDate,
                            ToDate,
                            NoOfDays,
                            Weeks,
                            Linked,
                            LAG(Linked, 1, 0) OVER (ORDER BY ToDate DESC) LinkedLag,
                            LEAD(Linked, 1, 0) OVER (ORDER BY ToDate DESC) LinkedLead
                  FROM      @table
                 )
        SELECT  FromDate,
                ToDate,
                NoOfDays,
                Weeks,
                Linked
        FROM    CTE_LagLead
        WHERE   Linked = 1 AND
                (LinkedLag = 1 OR
                 LinkedLead = 1)
        ORDER BY ToDate DESC;
    

    See working example

    【讨论】:

    • 这不是和我一样的答案吗?
    • 是的,几乎一模一样,赞成成为更快的打字机:)
    • @ChrisPickford:我已经编辑了我的问题,我的同事澄清说我们需要行包括Linked=0 的行
    【解决方案3】:

    这是我想出的答案:

    Select 
        * 
    from 
        #tmpAbsences 
    where 
        idcol between 1 AND (
        Select TOP 1 idcol from #tmpAbsences where Linked=0)
    

    这包括下图中的第 7 行:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-29
      • 2021-10-27
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多