sql - 从没有唯一键的表中删除重复行

标签 sql postgresql duplicates

我如何删除 Postgres 9 表中的重复行,这些行在每个字段上都是完全重复的,并且没有单独的字段可以用作唯一键,所以我不能只使用 GROUP BY 列并使用 NOT IN 语句。

我正在寻找单个 SQL 语句,而不是需要我创建临时表并将记录插入其中的解决方案。我知道该怎么做,但需要做更多工作才能适应我的自动化流程。

表定义:

jthinksearch=> \d releases_labels;
Unlogged table "discogs.releases_labels"
   Column   |  Type   | Modifiers
------------+---------+-----------
 label      | text    |
 release_id | integer |
 catno      | text    |
Indexes:
    "releases_labels_catno_idx" btree (catno)
    "releases_labels_name_idx" btree (label)
Foreign-key constraints:
    "foreign_did" FOREIGN KEY (release_id) REFERENCES release(id)

示例数据:

jthinksearch=> select * from releases_labels  where release_id=6155;
    label     | release_id |   catno
--------------+------------+------------
 Warp Records |       6155 | WAP 39 CDR
 Warp Records |       6155 | WAP 39 CDR

最佳答案

如果您有能力重写整个表,这可能是最简单的方法:

WITH Deleted AS (
  DELETE FROM discogs.releases_labels
  RETURNING *
)
INSERT INTO discogs.releases_labels
SELECT DISTINCT * FROM Deleted

如果您需要专门针对重复的记录,您可以使用内部的 ctid 字段,它唯一标识一行:

DELETE FROM discogs.releases_labels
WHERE ctid NOT IN (
  SELECT MIN(ctid)
  FROM discogs.releases_labels
  GROUP BY label, release_id, catno
)

要非常小心ctid;它随着时间的推移而变化。但您可以相信它在单个语句的范围内保持不变。

关于sql - 从没有唯一键的表中删除重复行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29409184/

相关文章:

sql - DELETE QUERY 第一次运行缓慢,但第二次(对于相同条件)运行速度很快 - 如何在第一次运行时使查询快速运行?

postgresql - 将秒数转换为 yyyy-mm-dd hh :mm:ss PostgreSQL

MySQL::在变量中运行 SQL 语句

sql - Insert 失败,但 identity value 增长了,这是否违反了 Atomicity 规则?

arrays - postgres将随机数插入数组列

postgresql - 从 JavaDB 迁移到 PostgreSQL 并且无法再访问数据库

java - 支持重复键的高效有序数据结构

php - 防止重复值进入 mysql 数据库 - 如果某些列与最后插入的行相似

java - 复制数组列表对象是否会复制原始数组列表中存储的内容?

sql - 如何使用分析获取唯一 ID 的汇总总数?