sql - PostgreSQL 删除除最旧记录以外的所有记录

标签 sql postgresql duplicates

我有一个 PostgreSQL 数据库,在多个 devicenames 上有多个 objectid 条目,但每个条目都有一个唯一的 timestamp .该表看起来像这样:

address | devicename | objectid      |  timestamp       
--------+------------+---------------+------------------------------
1.1.1.1 | device1    | vs_hub.ch1_25 | 2012-10-02 17:36:41.011629+00
1.1.1.2 | device2    | vs_hub.ch1_25 | 2012-10-02 17:48:01.755559+00
1.1.1.1 | device1    | vs_hub.ch1_25 | 2012-10-03 15:37:09.06065+00
1.1.1.2 | device2    | vs_hub.ch1_25 | 2012-10-03 15:48:33.93128+00
1.1.1.1 | device1    | vs_hub.ch1_25 | 2012-10-05 16:01:59.266779+00
1.1.1.2 | device2    | vs_hub.ch1_25 | 2012-10-05 16:13:46.843113+00
1.1.1.1 | device1    | vs_hub.ch1_25 | 2012-10-06 01:11:45.853361+00
1.1.1.2 | device2    | vs_hub.ch1_25 | 2012-10-06 01:23:21.204324+00

我想为每个 odjectiddevicename 删除除最旧条目以外的所有条目。在这种情况下,我想删除除以下内容之外的所有内容:

1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-02 17:36:41.011629+00
1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-02 17:48:01.755559+00

有办法吗?或者是否可以将“objectiddevicename”的最旧条目选择到临时表中?

最佳答案

应该这样做:

delete from devices
using (
   select ctid as cid, 
          row_number() over (partition by devicename, objectid order by timestamp asc) as rn
   from devices
) newest
where newest.cid = devices.ctid
and newest.rn <> 1;

它创建了一个派生表,该表将为(地址、设备名称、对象 ID)的每个组合分配唯一编号,为最早的一个(具有最小 timestamp 值的)编号 1。然后这个结果用于删除所有没有数字 1 的行。虚拟列 ctid 用于唯一标识这些行(它是 Postgres 提供的内部标识符)。

请注意,对于删除大量行,Erwin 的方法肯定会更快。

SQLFiddle 演示:http://www.sqlfiddle.com/#!1/5d9fe/2

关于sql - PostgreSQL 删除除最旧记录以外的所有记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12822457/

相关文章:

database - 执行批量更新和删除操作时避免 PostgreSQL 死锁

sql - 如何在 PostgreSQL 中创建只读用户?

python - 如何减少 numpy 数组中的行重复次数

sql - BigQuery 加载作业失败, "Could not parse ' Text' as bool"

MySql选择下一个较小的数字而不使用限制

SQL Server 在多个字段上进行透视

postgresql - 在 Ubuntu 16.04 LTS 中将 postgresql 从 9.3 升级到 9.5

apache-spark - Spark 数据帧删除重复项并保持第一

R:更改主题中的重复值

Mysql查询帮助比较多个url