根据用户减去上一行的下一行

时间:2018-09-17 16:14:10

标签: sql sql-server tsql sql-server-2008

我有以下数据,我想根据UserID从上一行中减去当前行。我尝试了下面的代码,没有得到我想要的

DECLARE @DATETBLE TABLE (UserID INT, Dates DATE)
INSERT INTO @DATETBLE VALUES
(1,'2018-01-01'), (1,'2018-01-02'), (1,'2018-01-03'),(1,'2018-01-13'),
(2,'2018-01-15'),(2,'2018-01-16'),(2,'2018-01-17'), (5,'2018-02-04'),
(5,'2018-02-05'),(5,'2018-02-06'),(5,'2018-02-11'), (5,'2018-02-17')


;with cte as (
      select UserID,Dates, row_number() over (order by UserID) as seqnum
      from @DATETBLE t
     )
select t.UserID,t.Dates, datediff(day,tprev.Dates,t.Dates)as diff
from cte t left outer join
     cte tprev
     on t.seqnum = tprev.seqnum + 1;

电流输出

UserID  Dates   diff
1   2018-01-01  NULL
1   2018-01-02  1
1   2018-01-03  1
1   2018-01-13  10
2   2018-01-15  2
2   2018-01-16  1
2   2018-01-17  1
5   2018-02-04  18
5   2018-02-05  1
5   2018-02-06  1
5   2018-02-11  5
5   2018-02-17  6

我的预期输出

  UserID    Dates   diff
    1   2018-01-01  NULL
    1   2018-01-02  1
    1   2018-01-03  1
    1   2018-01-13  10
    2   2018-01-15  NULL
    2   2018-01-16  1
    2   2018-01-17  1
    5   2018-02-04  NULL
    5   2018-02-05  1
    5   2018-02-06  1
    5   2018-02-11  5
    5   2018-02-17  6

2 个答案:

答案 0 :(得分:2)

如果您具有SQL Server 2012或更高版本,则可以将LAG()与按用户ID进行分区使用:

SELECT UserID
     , DATEDIFF(dd,COALESCE(LAG_DATES, Dates), Dates) as diff

FROM

(
SELECT UserID
     , Dates
     , LAG(Dates) OVER (PARTITION BY UserID ORDER BY Dates) as LAG_DATES

FROM @DATETBLE
) exp

这将为您在序列中的第一个日期提供0值而不是NULL值。

但是,由于您使用SQL Server 2008标记了该帖子,因此您可能需要使用不依赖于此窗口函数的方法。

答案 1 :(得分:2)

您的标签(sql-server-2008)建议我使用APPLY

select t.userid, t.dates, datediff(day, t1.dates, t.dates) as diff
from @DATETBLE t outer apply
     ( select top (1) t1.*
       from @DATETBLE t1
       where t1.userid = t.userid and
             t1.dates < t.dates
       order by t1.dates desc
     ) t1;