如何在 PostgreSQL 数据库中仅保留多个条目中的一个条目
How to keep only one entry among several in PostgreSQL database
我有一个监控网络的数据库(快照 table,其中包含一个 snapshot_date 列)。此生产数据库被错误的 crontab 淹没,导致同一设备每天生成许多快照。
我不会删除所有内容,但我只想为每个 snapshot_date 和每个 device_id 保留一个快照(列类型是“没有时区的时间戳”)所以减少此 table.
中的条目数
我不知道有什么简单的机制可以直接做到这一点 SQL。这能实现吗?
一个选项使用 distinct on
:
select distinct on (snapshot_date, device_id) *
from mytable
order by snapshot_date, device_id, snapshot_id
这保留了每个 snapshot_date
和 device_id
的一行,其中包含较小的 snapshot_id
。请注意,这假设 snapshot_id
是唯一的(或者至少对于每个 (snapshot_date, device_id)
元组都是唯一的)。
如果您想要 delete
语句,则:
delete from mytable t
using (
select snapshot_date, device_id, min(snapshot_id) snapshot_id
from mytable
group by snapshot_date, device_id
) t1
where
t.snapshot_date = t1.snapshot_date
and t.device_id = t1.device_id
and t.snapshot_id < t1.id
我有一个监控网络的数据库(快照 table,其中包含一个 snapshot_date 列)。此生产数据库被错误的 crontab 淹没,导致同一设备每天生成许多快照。
我不会删除所有内容,但我只想为每个 snapshot_date 和每个 device_id 保留一个快照(列类型是“没有时区的时间戳”)所以减少此 table.
中的条目数我不知道有什么简单的机制可以直接做到这一点 SQL。这能实现吗?
一个选项使用 distinct on
:
select distinct on (snapshot_date, device_id) *
from mytable
order by snapshot_date, device_id, snapshot_id
这保留了每个 snapshot_date
和 device_id
的一行,其中包含较小的 snapshot_id
。请注意,这假设 snapshot_id
是唯一的(或者至少对于每个 (snapshot_date, device_id)
元组都是唯一的)。
如果您想要 delete
语句,则:
delete from mytable t
using (
select snapshot_date, device_id, min(snapshot_id) snapshot_id
from mytable
group by snapshot_date, device_id
) t1
where
t.snapshot_date = t1.snapshot_date
and t.device_id = t1.device_id
and t.snapshot_id < t1.id