我想在某些条件下分配排名
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;
通过此查询,我得到以下输出,
虽然,我想要这样的东西(如下图所示)
请帮助我了解我在查询中遗漏了什么以及如何解决这个问题。
谢谢!!
我们可以尝试在子查询中使用LAG
window函数获取之前的每一个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
我想根据数据集中每个 '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;
通过此查询,我得到以下输出,
虽然,我想要这样的东西(如下图所示)
请帮助我了解我在查询中遗漏了什么以及如何解决这个问题。 谢谢!!
我们可以尝试在子查询中使用LAG
window函数获取之前的每一个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 |