如何删除在 postgresql 中按日期列排序的每个分组结果中的第一行
How to remove first row in every grouped result ordered on date column in postgresql
我有一个 sql 数据 (table),它由 n
列组成,但有 3 列特别令人感兴趣
claim_id
patient_id
admission_date
1
p_1
2001-01-01
2
p_2
2001-02-01
3
p_1
2001-01-01
4
p_3
2001-02-02
5
p_2
2001-03-01
6
p_2
2001-04-01
7
p_1
2001-04-01
我想要的是删除每个 patient_id
的第一行(基于 admission_date
)。如果任何患者在 his/her 第一个入院日期有两行(例如 patient_id = p_1
有 2 行 1 & 3
且入院日期相同),则删除所有这些行;得到这样的输出
claim_id
patient_id
admission_date
5
p_2
2001-03-01
6
p_2
2001-04-01
7
p_1
2001-04-01
我不太熟悉 sql,但我可以使用 duplicated
在 R
中轻松做到这一点。在 POSTGRESQL 中是否有类似的内存效率(我必须至少过滤 1000 万行)?
我试过什么? sql 里基本上什么都没有。如果该数据较小,我可以将其导出到 R 中并在那里进行分析。
请帮忙。
您可以为此使用 window 函数:
select claim_id, patient_id, admission_date
from (
select claim_id, patient_id, admission_date,
dense_rank() over (partition by patient_id order by admission_date) as rn
from the_table
) t
where rn > 1;
dense_rank()
为按 admission_date 排序的每个 patient_id 创建序号。如果两行具有相同的 admission_date,它们将获得相同的“等级”。外部查询中的 WHERE 子句只是删除每个患者的“第一”行。
我们可以在这里使用存在的逻辑:
SELECT claim_id, patient_id, admission_date
FROM yourTable t1
WHERE EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.patient_id = t1.patient_id AND
t2.claim_id < t1.claim_id);
鉴于某些患者似乎在同一天多次入院,我使用 claim_id
作为有序标识符来确定先入院。
如果上述性能令人担忧,那么以下索引应该会大大加快速度:
CREATE INDEX idx ON yourTable (patient_id, claim_id);
我有一个 sql 数据 (table),它由 n
列组成,但有 3 列特别令人感兴趣
claim_id | patient_id | admission_date |
---|---|---|
1 | p_1 | 2001-01-01 |
2 | p_2 | 2001-02-01 |
3 | p_1 | 2001-01-01 |
4 | p_3 | 2001-02-02 |
5 | p_2 | 2001-03-01 |
6 | p_2 | 2001-04-01 |
7 | p_1 | 2001-04-01 |
我想要的是删除每个 patient_id
的第一行(基于 admission_date
)。如果任何患者在 his/her 第一个入院日期有两行(例如 patient_id = p_1
有 2 行 1 & 3
且入院日期相同),则删除所有这些行;得到这样的输出
claim_id | patient_id | admission_date |
---|---|---|
5 | p_2 | 2001-03-01 |
6 | p_2 | 2001-04-01 |
7 | p_1 | 2001-04-01 |
我不太熟悉 sql,但我可以使用 duplicated
在 R
中轻松做到这一点。在 POSTGRESQL 中是否有类似的内存效率(我必须至少过滤 1000 万行)?
我试过什么? sql 里基本上什么都没有。如果该数据较小,我可以将其导出到 R 中并在那里进行分析。
请帮忙。
您可以为此使用 window 函数:
select claim_id, patient_id, admission_date
from (
select claim_id, patient_id, admission_date,
dense_rank() over (partition by patient_id order by admission_date) as rn
from the_table
) t
where rn > 1;
dense_rank()
为按 admission_date 排序的每个 patient_id 创建序号。如果两行具有相同的 admission_date,它们将获得相同的“等级”。外部查询中的 WHERE 子句只是删除每个患者的“第一”行。
我们可以在这里使用存在的逻辑:
SELECT claim_id, patient_id, admission_date
FROM yourTable t1
WHERE EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.patient_id = t1.patient_id AND
t2.claim_id < t1.claim_id);
鉴于某些患者似乎在同一天多次入院,我使用 claim_id
作为有序标识符来确定先入院。
如果上述性能令人担忧,那么以下索引应该会大大加快速度:
CREATE INDEX idx ON yourTable (patient_id, claim_id);