SQL中类似记录之间的日期差异

时间:2015-10-26 18:41:15

标签: sql oracle

我有一张桌子,需要在两个日期之间获得一组非常相似的记录。我今天尝试了一些方法,但似乎无法让这个方法起作用。

示例表:

  Payment_ID | Created_Date | Version_ID |      Status
 ----------------------------------------------------------
     1526    | 20/10/2015   |      1     | Opened
     1526    | 20/10/2015   |      2     | Verified Open
     1526    | 22/10/2015   |      3     | Assigned
     1526    | 23/10/2015   |      4     | Contact Made
     1859    | 20/10/2015   |      1     | Opened
     1859    | 20/10/2015   |      2     | Verified Open
     1859    | 22/10/2015   |      3     | Assigned
     1859    | 22/10/2015   |      3.5   | Re-Assigned
     1859    | 22/10/2015   |      4.5   | Contact Failed
     1859    | 23/10/2015   |      4     | Contact Made
     1859    | 24/10/2015   |      5     | Assigned Updated
     1859    | 25/10/2015   |      6     | Contact Made
     1859    | 26/10/2015   |      7     | Resolved
     1859    | 21/10/2015   |      8     | Closed
     1852    | 26/10/2015   |      1     | Opened
     1778    | 21/09/2015   |      1     | Opened
     1778    | 22/09/2015   |      2     | Verified Open
     1778    | 23/09/2015   |      3     | Assigned
     1778    | 24/09/2015   |      4     | Contact Made
     1778    | 25/09/2015   |      5     | Assigned Updated

要求是返回给定Payment_ID的{​​{1}}和StatusDateDiff,在这种情况下返回Status一个,如果Contact_Made则仅返回第一个Payment_ID有多个,然后取得任何一个日期和上一个状态日期之间的差异。

因此,在24/10/2015上取1526“Contact_Made”,之前的状态是23/10/2015,不管是什么,所以差异为1

对于上述情况,它看起来像这样:

  Payment_ID | StatusDateDiff
 -----------------------------
    1526     |       1
    1859     |       1
    1852     |       0
    1778     |       1

我尝试了一些子查询来获取distinct Payment_IDMin(Created_Date),但这样就会产生重复一次。

还尝试了一个Common Table Expression,但导致相同 - 虽然我对它们不太熟悉。

任何想法都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

使用LAG()(在SQL Server 2012 +中提供):

select payment_id, datediff(day, prev_created_date, created_date)
from (select t.*,
             lag(created_date) over (partition by payment_id order by created_date) as prev_created_date,
             row_number() over (partition by payment_id, status order by created_date) as seqnum
      from t
     ) t
where status = 'Contact Made' and seqnum = 1;

答案 1 :(得分:0)

这是未经测试的,但这应该指向正确的方向。您可以使用窗口ROW_NUMBER()函数来确定哪些值是最新值,并使用DATEDIFF()查找它们不同的天数。

编辑:我刚注意到你有一个SQL Server标记和一个Oracle标记 - 这个答案适用于SQL Server

;With Ver As
(
    Select  *,
            Row_Number() Over (Partition By Payment_Id Order By Version Desc) Row_Number
    From    Table
)
Select      Latest.Payment_Id,
            DateDiff(Day, Coalesce(Previous.Created_Date, Latest.CreatedDate), Latest.CreatedDate) As StatusDateDiff
From        Ver     As  Latest
Left Join   Ver     As  Previous    On  Latest.Payment_Id = Previous.Payment_Id
                                    And Previous.Row_Number = 2
Where       Latest.Row_Number = 1