t-SQL:用动态滞后计算日期差异

时间:2017-12-09 22:40:39

标签: sql sql-server tsql lag over-clause

有没有办法计算不一致的后续日期之间的持续时间,使用SQL Server 2017的OVER子句并且没有连接或子查询?这可能是使用LAG函数使用一些动态计算的滞后参数来完成的吗?

例如,trx 2& 3是在同一天,所以我们计算从1到2和从1到3的持续时间。由于4发生在不同的一天,其持续时间从3到4.由于trx 5与4的同一天,我们计算其持续时间从3到5,依此类推。

CREATE TABLE #t(Trx TINYINT, DT DATE);
INSERT INTO #t SELECT 1, '1/1/17';
INSERT INTO #t SELECT 2, '1/5/17';
INSERT INTO #t SELECT 3, '1/5/17';
INSERT INTO #t SELECT 4, '1/15/17';
INSERT INTO #t SELECT 5, '1/15/17';
INSERT INTO #t SELECT 6, '1/20/17';

下面是一个带连接的简单实现,但是可以使用一些OVER子句函数(没有连接或子查询)内联吗?

SELECT c.Trx, c.DT, 
DurO=DATEDIFF(DAY, LAG(c.DT,1) OVER(ORDER BY c.DT), c.DT), -- does not use join
DurJ=DATEDIFF(DAY, MAX(p.DT), c.DT) -- uses join
FROM #t c LEFT JOIN #t p ON c.DT > p.DT
GROUP BY c.Trx, c.DT
ORDER BY c.DT

请注意,DurJ计算正确,但DurO不是:

Trx DT          DurO    DurJ
1   2017-01-01  NULL    NULL
2   2017-01-05  4       4
3   2017-01-05  0       4
4   2017-01-15  10      10
5   2017-01-15  0       10
6   2017-01-20  5       5

如果需要,我会进一步澄清任何具体细节。

注意:不是重复的问题。此问题仅涉及一个日期列,没有项目分组。顺便说一下,这两个问题都没有一个令人满意的解决方案。

1 个答案:

答案 0 :(得分:2)

使用dense_rank将相同的日期视为一个组,并使用它来获得相同的差异。

select trx,beg,sum(diff) over(partition by grp) as diff
from (select trx,beg,datediff(day,lag(beg) over(order by beg),beg) as diff,
      dense_rank() over(order by beg) as grp
      from #t
     ) t

Per @ Alexey的评论,实际上并不需要dense_rank。您可以使用beg日期进行分组。

select trx,beg,sum(diff) over(partition by beg) as diff
from (select trx,beg,datediff(day,lag(beg) over(order by beg),beg) as diff
      from #t 
     ) t