我想在某些条件下分配排名

I want to assign rank following with some condition

我想根据数据集中每个 'patient_id' 的 'svcdate' 的顺序将排名分配给 'drug_name'。 (这里,为了描述问题,我只在图片中显示了一个 patient_id)

select patient_id
    ,svcdate
    ,drug_name
    ,dense_rank() over(partition by patient_id order by first_date) as rank
from (
    select *
        ,first_value(svcdate) over (
           partition by patient_id, drug_name 
           order by svcdate) as first_date
    from table
)
order by 1,2;

通过此查询,我得到以下输出,

虽然,我想要这样的东西(如下图所示)

请帮助我了解我在查询中遗漏了什么以及如何解决这个问题。 谢谢!!

我们可以尝试在子查询中使用LAGwindow函数获取之前的每一个drug_name,然后通过条件聚合window函数进行比较使得rank列。

select patient_id
    ,svcdate
    ,drug_name
    ,SUM(CASE WHEN prev_drug_name <> drug_name THEN 1 ELSE 0 END) over(partition by patient_id order by first_date) as rank
from (
    select *,LAG(drug_name) OVER(partition by patient_id ORDER BY svcdate) prev_drug_name
    from table
)
order by 1,2;

将此 CTE 用于数据:


with data(patient_id, svcdate, drug_name) as (
    select * from values
    (110, '2018-08-09'::date, 'TRANEXAMIC ACID'),
    (110, '2020-05-28'::date, 'TAKHZYRO'),
    (110, '2020-06-10'::date, 'ICATIBANT'),
    (110, '2020-06-24'::date, 'TAKHZYRO'),
    (110, '2020-07-22'::date, 'TAKHZYRO'),
    (110, '2020-07-24'::date, 'ICATIBANT'),
    (110, '2020-08-31'::date, 'ICATIBANT'),
    (110, '2020-08-31'::date, 'TAKHZYRO')
)

并且使用 CONDITONAL_CHANGE_EVENT 可以满足您的需求

select patient_id
    ,svcdate
    ,drug_name
    ,CONDITIONAL_CHANGE_EVENT( drug_name ) OVER ( 
        PARTITION BY patient_id ORDER BY svcdate )+1 as rank
from data
order by 1,2;

给出:

PATIENT_ID SVCDATE DRUG_NAME RANK
110 2018-08-09 TRANEXAMIC ACID 1
110 2020-05-28 TAKHZYRO 2
110 2020-06-10 ICATIBANT 3
110 2020-06-24 TAKHZYRO 4
110 2020-07-22 TAKHZYRO 4
110 2020-07-24 ICATIBANT 5
110 2020-08-31 ICATIBANT 5
110 2020-08-31 TAKHZYRO 6