【问题标题】:How to keep only one entry among several in PostgreSQL database如何在PostgreSQL数据库中只保留一个条目
【发布时间】:2021-01-28 22:37:19
【问题描述】:

我有一个监控网络的数据库(快照表,其中包含一个 snapshot_date 列)。这个生产数据库被一个有问题的 crontab 淹没,导致每天为同一设备生成许多快照。

我不会删除所有内容,但我只想为每个 snapshot_date 和每个 device_id 保留一个快照(列类型为“无时区的时间戳”),以减少此表中的条目数。

我不知道在普通 SQL 中执行此操作的任何简单机制。这可以实现吗?

【问题讨论】:

  • snapshot_id 是唯一的/PK 吗?
  • use text, not images/links, for text--including tables & ERDs。仅将图像用于无法表达为文本或增强文本的内容。在图像中包含图例/键和说明。这是一个常见问题解答。请在考虑发布之前阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:stackoverflow.com 和标签;阅读许多答案。反映你的研究。见

标签: sql postgresql duplicates inner-join sql-delete


【解决方案1】:

一个选项使用distinct on

select distinct on (snapshot_date, device_id) *
from mytable 
order by snapshot_date, device_id, snapshot_id

这将保留每个 snapshot_datedevice_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

【讨论】:

  • 感谢您的回答。 snapshot_id 确实是主键。然而,snapshot_date 是一个日期时间(没有时区的时间戳)。它遵循以下格式:2020-10-14 03:49:59。我的问题是,我在同一日期(即在此示例中为2020-10-14)有许多不同时间的同一设备的大量快照。我想为每台设备提供最新信息,并删除其他所有设备(每个日期一个快照)。
  • @MathiasB.:好的,这从你的问题中并不明显。您可以改用snapshot_date::date
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多