【问题标题】:Check difference in dates on separate SQL rows检查不同 SQL 行的日期差异
【发布时间】:2019-01-15 20:26:16
【问题描述】:

我有一个表格,用于存储对象进度的连续期间的开始日期和结束日期。这是为了跟踪每个对象何时进入其进度的下一步

例如:

ObjectNum | Stage | StartDate | EndDate
1         |1      |2018-01-01 | 2018-02-24
1         |2      |2018-02-25 |
2         |1      |2018-01-01 |

SQL 中有没有办法搜索这张表并找到任何对象,其中一个阶段的结束日期与下一个顺序阶段的开始日期之间的差异超过 1 天?

亲切的问候

马特

【问题讨论】:

  • 您还会遇到多行重叠开始/结束的问题吗?如果是这样,您可能需要组合这些行以首先找到真正的开始/结束,然后使用像 jnevill's answer 这样的技术

标签: sql sql-server-2008


【解决方案1】:

更新给那些对此感兴趣的人。鉴于 Lead() 在 SQL2008 中不起作用,这是我采用的解决方案

Select ObjectNum from Object m join
       (SELECT ObjectNum, StartDate, EndDate, row_number() over (PARTITION by ObjectNum order by StartDate asc)as Row from STATHIS) s1
       on s1.ObjectNum = m.ObjectNum
       join
       (SELECT ObjectNum, StartDate, EndDate, row_number() over (PARTITION by ObjectNum order by StartDate asc)as Row from STATHIS) s2
       on s1.Row +1 = s2.Row and s1.ObjectNum = s2.ObjectNum
where DATEDIFF(DAY,s1.EndDate,s2.StartDate) > 1

【讨论】:

    【解决方案2】:

    您可以在ObjectNumStage 上将表连接到自身,然后进行测试:

    SELECT
        t1.ObjectNum,
        t1.Stage,
        t1.StartDate,
        t1.EndDate,
        DATEDIFF("D", t1.EndDate, t2.StartDate) as StageGapInDays
    FROM table t1
            INNER JOIN table t2 
                ON t1.ObjectNum = t2.ObjectNum
                    AND t1.Stage + 1 = t2.Stage
    Where StageGapInDays > 1
    

    您还可以在子查询中使用LEAD() 窗口函数,这样您只需扫描一次表并避免连接:

    SELECT *
    FROM
        (
            SELECT
                ObjectNum,
                Stage,
                StartDate,
                EndDate,
                DATEDIFF(day, EndDate, LEAD(StartDate) OVER (PARTITION BY ObjectNum ORDER BY Stage)) as StageGapInDays
            FROM table      
        ) subquery
    Where StageGapInDays > 1
    

    第二个将捕获Stage 1NO Stage 2Stage 3 的情况,其中Stage 1Stage 3 之间的差距大于一天。第一个查询不会捕捉到这种情况。

    【讨论】:

    • 感谢 JNevill。我不得不使用联接,因为显然不能在服务器 2008 中使用。希望上级尽快同意升级!
    • 天哪! 2008. 它确实具有一些窗口功能。您也许可以用Max(StartDate) OVER (PARTITION BY ObjectNum ORDER BY Stage ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) 替换那个LEAD() 我相信Max() OVER... 是在那个版本中添加的。 (如果您喜欢冒险。
    • 我实际上最终使用 row_number() 功能将 2 个表放在一起,并将所有行都增加了一个,这似乎可以解决问题。我已将您的答案标记为答案,因为 Lead() 本来是完美的。我将在下面为那些不能使用 Lead() 的人添加我的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 2017-12-15
    • 2014-01-14
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多