首页 > 解决方案 > SQL:有没有办法捕获“每 45 天一次”?

问题描述

第一次发帖,但多年来我偶然发现了 Stackoverflow。

患者可能会在几个月内多次接受特定的实验室测试。但是,为了减少重复,我只想每 45 天捕获一次这些结果。因此,如果患者今天进行了实验室测试,我可以忽略接下来 45 天的实验室测试。但是,如果患者在第 51 天接受了重复的实验室测试,我想重置“时钟”并忽略接下来 45 天的实验室测试。

这通常是我想要做的事情:

PatientID    Date    DayNum    KeepThis?    DaysSinceLastKeptTest
    1      3/2/2020     0        Yes                 0
    1      3/5/2020     3                            3
    1      4/6/2020    35                           35
    1      4/10/2020   39                           39
    1      5/15/2020   74        Yes                 0 (more than 45 days since 3/2 test)
    1      5/25/2020   84                           10
    1      5/30/2020   89                           15
    1      6/6/2020    96                           22
    1      7/1/2020   121        Yes                 0 (more than 45 days since 5/15 test)
    1      7/4/2020   124                            3
    1      7/15/2020  135                           14

(在我的最终产品中,我不一定需要 DayNum、KeepThis 或 DaysSinceLastKeptTest 列。我只需要 3 个“是”行。)

我正在尝试在 SQL 中执行此操作,但无法弄清楚。我考虑过临时表或子查询,我只是在学习 OVER/PARTITION BY 作为解决这个问题的一种可能方法。

感谢您提供的任何帮助或想法。谢谢!

标签: sqlsql-servertsql

解决方案


使用递归 CTE,您可以做到:

with cte_rn
as
(
    select *,ROW_NUMBER() over (partition by patientId order by testdate ) as seq
    from patients
),
cte_recursive
as
(
    select *,cte_rn.testdate as usedTestDate,1 as toUse
    from cte_rn
    where seq=1
    union all
    select rn.patientid,rn.testdate,rn.seq,case when datediff(day ,r.usedTestDate,rn.testdate)>45 then rn.testdate else  r.usedTestDate end  as usedTestDate,case when datediff(day ,r.usedTestDate,rn.testdate)>45 then 1 else 0 end as toUse
    from cte_recursive r
    join cte_rn rn
        on r.seq = rn.seq-1


)

select *
from cte_recursive

推荐阅读