SQL 循环记录的查询

SQL query to loop through records

我有一个 table 有一百万条记录。这是带有一些示例数据点的 table 的结构 -

patient   claim   thru_dt   cd   start     
322       65      20200201  42   20181008  
322       65      20200202  42             
322       95      20200203  52             
122       05      20200105  23             
122       05      20200115  42   20190102  
122       05      20200116  42            

我需要编写一个查询来生成此输出 -

patient   claim   thru_dt   cd   start     
322       65      20200201  42   20181008    
322       65      20200202  42   20181008    
322       95      20200203  52   20181008    
122       05      20200105  23               
122       05      20200115  42   20190102    
122       05      20200416  42      

之所以给予患者 322 的第二次索赔 20181008 是因为第一个和第二个具有相同的 cd 价值。

患者 322 的第三次索赔即使没有相同的 cd 值也被赋予 20181008 值的原因是因为它是患者的最后一次索赔。

患者 122 的第一个索赔仍然为 NULL 的原因是该索赔的 cd 值不等于 42。

尽管患者 122 的第三次索赔具有相同的 cd 值,但其第三次索赔未被赋予 20190102 值的原因是因为他们先前索赔中的 thru_dt 更多相隔超过 30 天。

这是我目前尝试过的 -

--This orders claims using row_number
DECLARE @min_record int;
DECLARE @max_record int;

select 
    @min_record = MIN(row_num), 
    @max_record = MAX(row_num) 
from 
(
    select *, 
    row_number() over(partition by patient order by thru_dt) as row_num
    from 
    table
)

while @min_record <= @max_record
begin 
    --Logic I need help with 
    SET @min_record = @min_record + 1
end 

我认为横向连接和条件表达式可以更简单地实现您想要的逻辑:

select t.*,
    case 
        when t.start is null and (
            s.cd = t.cd 
            or row_number() over(partition by t.patient order by t.thru_dt desc) = 1
        )
        then s.start
        else t.start
    end new_start
from mytable t
outer apply (
    select top (1) s.*
    from mytable s
    where 
        s.patient = t.patient 
        and s.start is not null
        and s.thru_dt >= dateadd(day, -30, t.thru_dt)
    order by s.thru_dt desc
) s
order by patient desc, thru_dt

Demo on DB Fiddle:

patient | claim | thru_dt    | cd | start      | new_start 
------: | ----: | :--------- | -: | :--------- | :---------
    322 |    65 | 2020-02-01 | 42 | 2018-10-08 | 2018-10-08
    322 |    65 | 2020-02-02 | 42 | null       | 2018-10-08
    322 |    95 | 2020-02-03 | 52 | null       | 2018-10-08
    122 |     5 | 2020-01-05 | 23 | null       | null      
    122 |     5 | 2020-01-15 | 42 | 2019-01-02 | 2019-01-02
    122 |     5 | 2020-04-16 | 42 | null       | null