根据条件创建分组

Creating groupings based on criteria

希望得到一些帮助解决以下差距和孤岛问题

我有以下示例数据集:

MEM_ID CLM_ID ADM_DT DCHG_DT PROV
1 111 01-01-2021 01-01-2021 1
1 112 01-01-2021 02-01-2021 1
1 113 01-01-2021 01-01-2021 1
1 114 01-01-2021 01-01-2021 1
1 115 01-01-2021 01-01-2021 1
1 116 02-15-2021 02-15-2021 2
1 117 02-15-2021 02-15-2021 3
1 118 02-16-2021 02-16-2021 3
2 211 01-01-2021 01-01-2021 1
2 212 03-01-2021 03-01-2021 2
3 311 02-01-2021 02-01-2021 1
3 312 02-01-2021 02-01-2021 2

我想要完成的是以下内容:

基于 MEM_ID、PROV 和 ADM_DT 的独特组合,我想将事件分组为 1。我还需要将同一 [=42] 中的任何其他事件分组=] 和 PROV 如果 DCHG_DT 与 ADM_DT 相同或最多提前 1 天。

最终结果应该是这样的:

MEM_ID CLM_ID ADM_DT DCHG_DT PROV GROUP
1 111 01-01-2021 01-01-2021 1 1
1 112 01-01-2021 02-01-2021 1 1
1 113 01-01-2021 01-01-2021 1 1
1 114 01-01-2021 01-01-2021 1 1
1 115 01-01-2021 01-01-2021 1 1
1 116 02-15-2021 02-15-2021 2 2
1 117 02-15-2021 02-15-2021 3 3
1 118 02-16-2021 02-16-2021 3 3
2 211 01-01-2021 01-01-2021 1 1
2 212 03-01-2021 03-01-2021 2 2
3 311 02-01-2021 02-01-2021 1 1
3 312 02-01-2021 02-01-2021 2 2

在预期的输出中,MEM_ID 1 的前 5 条记录被分到第 1 组,因为它符合具有相同 MEM_ID、PROV 和 ADM_DT 组合的条件.记录 6 和 7 具有相同的 MEM_ID 和 ADM_DT 组合,但不同的 PROV,因此它们被分成组 2 和 3。记录 8 具有相同的 MEM_ID 和 PROV 组合,但 ADM_DT 与记录 7 的不同。但是,由于记录 8 中的 ADM_DT 与记录 7 中的 DCHG_DT 相差不到 1 天,因此它被视为同一事件并分配到第 3 组。其余数据点非常直截了当地说明了它们按原样分组的原因。

我尝试了以下代码:


SELECT DISTINCT MEM_ID
    , PROV
    , CLM_ID
    , ADM_DT
    , DCHG_DT
    , sum(ISSTART) OVER (PARTITION BY MEM_ID, ADM_DT ORDER BY ADM_DT, DCHG_DT rows unbounded preceding) AS GROUP

FROM (
    SELECT DISTINCT MEM_ID
        , PROV
        , CLM_ID
        , ADM_DT
        , DCHG_DT
        , CASE 
            WHEN PROV = LAG(PROV) OVER (PARTITION BY MEM_ID ORDER BY ADM_DT, DCHG_DT)
                AND (
                        (
                        ADM_DT = LAG(DCHG_DT) OVER (PARTITION BY MEM_ID ORDER BY ADM_DT, DCHG_DT)
                        )
                    OR (
                        ADM_DT = LAG(DCHG_DT + 1) OVER (PARTITION BY MEM_ID ORDER BY ADM_DT, DCHG_DT)
                        )
                    )
                THEN 0
            ELSE 1
            END AS ISSTART
    
    FROM c1
    ) t

但是这让我在分组时出错。

使用上面的代码我得到了类似的东西:

MEM_ID CLM_ID ADM_DT DCHG_DT PROV GROUP
1 111 01-01-2021 01-01-2021 1 0
1 112 01-01-2021 02-01-2021 1 1
1 113 01-01-2021 01-01-2021 1 1
1 114 01-01-2021 01-01-2021 1 1
1 115 01-01-2021 01-01-2021 1 1
1 116 02-15-2021 02-15-2021 2 0
1 117 02-15-2021 02-15-2021 3 0
1 118 02-16-2021 02-16-2021 3 1

感谢任何帮助!

谢谢!

select *,
    sum(gap) over (partition by MEM_ID order by ADM_DT, CLM_ID) as grp
from (
    select *,
        case when
                ADM_DT =
                lag(ADM_DT)  over (partition by MEM_ID, PROV order by ADM_DT, CLM_ID)
                or           
            days_between(
                ADM_DT,
                lag(DCHG_DT) over (partition by MEM_ID, PROV order by ADM_DT, CLM_ID)
            ) in (0, 1) -- not sure if zero is valid
            then 0 else 1 end as gap
    from c1
) t
order by MEM_ID, PROV, GRP, ADM_DT

如果您没有可用的 days_between() 那么显然您可以使用 when lag(DCHG_DT) over (partition by MEM_ID, PROV order by ADM_DT, CLM_ID) - ADM_DT

请注意,Postgres 以不同方式处理日期数学,但您可以尝试一下 https://dbfiddle.uk/?rdbms=postgres_13&fiddle=95f28f3d57c520d1e45422b588dcdd85