0

有没有办法使用 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

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

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

4

1 回答 1

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

根据@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
于 2017-12-09T22:55:11.130 回答