SQL中的滚动总数,超过90时将重置为0

问题描述 投票:1回答:1

第一次发布。在过去的6个月中学习了SQL,非常感谢您的帮助。我的数据结构如下:

DECLARE @tmp4 as TABLE (
    AccountNumber int,
    Date            date,
    DateRank        int
)

INSERT INTO @tmp4
VALUES (001, '11/13/2018' , 1)
, (002, '12/19/2018', 2)
, (003, '1/23/2019' , 3)
, (004, '2/5/2019' , 4)
, (005, '3/10/2019' , 5)
, (006, '3/20/2019' , 6)
, (007, '4/8/2019' , 7)
, (008, '5/20/2019' , 8)

我需要使用此数据来计算滚动总数,一旦达到90天的阈值,该滚动总数将重置为0。我已经使用DateDiff函数计算连续日期之间的DateDiffs,并尝试使用LAG和其他窗口函数进行多种操作,但无法重置它。目标是找到只能每90天出现一次的“索引访问”。因此,我的计划是让一个字段在首次访问后读取0,并在下次访问90天后重置为0,以供下次访问,然后仅拉取访问值为0。

我尝试过的一种解决方案对于大多数集合都是正确的,但是没有为上述集合返回正确的值(第4行和第8行应从“索引访问”开始重新开始)。我期望此查询的结果为:

帐户日期DateRank滚动总计

001 | '11 / 13/2018'| 1 | 0

002 | '12 / 19/2018'| 2 | 35

003 |'1/23/2019'| 3 | 71

004 |'2/5/2019'| 4 | 84

005 |'3/10/2019'| 5 | 0(不是117)

006 |'3/20/2019'| 6 | 10

007 |'4/8/2019'| 7 | 29

008 |'5/20/2019'| 8 | 71感谢您的帮助。

这是我尝试的代码:

DECLARE @tmp2 as TABLE
(EmrNumber      varchar(255)
, AdmitDateTime datetime
, DateRank      int
, LagDateDiff   int
, RunningTotal  int
)

INSERT INTO @tmp2

SELECT tmp1.EmrNumber
        , tmp1.AdmitDateTime
        , tmp1.DateRank
--, LAG(tmp1.AdmitDateTime) OVER(PARTITION BY tmp1.EmrNumber ORDER BY tmp1.DateRank) as NextAdmitDate
, -DATEDIFF(DAY, tmp1.AdmitDateTime, LAG(tmp1.AdmitDateTime) OVER(PARTITION BY tmp1.EmrNumber ORDER BY tmp1.DateRank)) LagDateDiff
, IIF((SELECT SUM(sumt.total)
        FROM (
                SELECT -DATEDIFF(DAY, tmpsum.AdmitDateTime, LAG(tmpsum.AdmitDateTime) OVER(PARTITION BY tmpsum.EmrNumber ORDER BY tmpsum.DateRank)) total
                FROM @tmp tmpsum
                WHERE tmp1.EmrNumber = tmpsum.EmrNumber 
                AND tmpsum.AdmitDateTime <= tmp1.AdmitDateTime
        ) sumt) IS NULL, 0, (SELECT SUM(sumt.total)
        FROM (
                SELECT -DATEDIFF(DAY, tmpsum.AdmitDateTime, LAG(tmpsum.AdmitDateTime) OVER(PARTITION BY tmpsum.EmrNumber ORDER BY tmpsum.DateRank)) total
                FROM @tmp tmpsum
                WHERE tmp1.EmrNumber = tmpsum.EmrNumber 
                AND tmpsum.AdmitDateTime <= tmp1.AdmitDateTime
        ) sumt) ) as RunningTotal 

FROM @tmp tmp1 

SELECT *
, CASE WHEN LagDateDiff >90 THEN 0
    WHEN RunningTotal = 0 THEN 0
    ELSE LAG(LagDateDiff) OVER(PARTITION BY EmrNumber ORDER BY DateRank) + RunningTotal END AS RollingTotal
FROM @tmp2
sql sql-server tsql date recursive-query
1个回答
0
投票

您需要对此进行递归查询,因为必须逐行逐行检查运行总计:

with cte as (
    select 
        Account, 
        Date, 
        DateRank, 
        0 RollingTotal
    from @tmp4
    where DateRank = 1
    union all
    select 
        t.Account, 
        t.Date,
        t.DateRank,
        case when RollingTotal + datediff(day, c.Date, t.Date) > 90
            then 0
            else RollingTotal  + datediff(day, c.Date, t.Date)
        end
    from cte c
    inner join @tmp4 t on t.DateRank = c.DateRank + 1
)
select * from cte

cte的锚点选择第一条记录(如DateRank所示。然后,递归部分逐行处理行,并在超过90时重置运行计数。

© www.soinside.com 2019 - 2024. All rights reserved.