sql - 迭代删除重复记录

标签 sql postgresql

对于表中的每个 user_id(组),我想删除除每个组中具有最高 ID 的记录之外的所有记录。类似于此:Delete all records except the most recent one?

在我的例子中它看起来像:

DELETE FROM logins
WHERE user_id IS NOT NULL AND id NOT IN (SELECT MAX(id) FROM logins WHERE user_id IS NOT NULL GROUP BY user_id)

问题是,该表包含 100 多条记录,因此在这样的单个查询中执行此操作在性能方面是不可能的。

还有什么其他方法可以做到这一点,例如在一些批处理?

最佳答案

我倾向于将 delete 表述为:

DELETE FROM logins l
    WHERE l.user_id IS NOT NULL AND
          l.id <> (SELECT MAX(l2.id)
                   FROM logins l2
                   WHERE l2.user_id = l.user_id
                  );

这可以轻松利用 logics(user_id, id) 上的索引。但是,如果要删除大量行,通常最好截断表并重新创建:

create table temp_logics as
    select l.*
    from logins
    where l.id = (SELECT MAX(l2.id)
                  FROM logins l2
                  WHERE l2.user_id = l.user_id
                 );

truncate table logins;

insert into logins
    select * from temp_logins;

如果您采用这种方法,请务必在截断第二个表之前验证 temp_logins。实际上,您不想为中间表使用临时表,因为数据库可能会发生某些事情——您会丢失数据。

关于sql - 迭代删除重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47137642/

相关文章:

sql - 如何使用 Select SQL Server 查询检索所有子项

Java DBUnit AmbigouslyTableNameException 错误抛出

mysql - 将 MySQL 数据库内容迁移到 PostgreSQL

sql - 如何将 N 个数据库表与一个主表绑定(bind)?

sql - 如何使用单个查询将一行拆分为多行?

sql - 将多个计数分组,每一行代表一个 ID

postgresql - PostgreSQL 中的动态限制

sql-server - 唯一的 RID 会是 "overflow"吗?

sql - Postgres 中的动态 UNION ALL 查询

sql - 将相似的行与两个相同的值组合起来