4

我有一个有很多重复行且没有主键的表。
我只想删除重复的记录,但是当我尝试这样做时,它会删除所有对等点。

如何ROWID从 Postgres 的表中找到?

4

3 回答 3

5

在 PostgreSQL 上,行的物理位置称为 CTID。

因此,如果您想查看它,请使用如下查询:

SELECT CTID FROM table_name

要在 DELETE 语句中使用它来删除重复的记录,请像这样使用它:

DELETE FROM table_name WHERE CTID NOT IN (
  SELECT RECID FROM 
    (SELECT MIN(CTID) AS RECID, other_columns 
      FROM table_name GROUP BY other_columns) 
  a);

请记住,table_name 是所需的表,而 other_columns 是您要用于过滤的列。

IE:

DELETE FROM user_department WHERE CTID NOT IN (
  SELECT RECID FROM 
    (SELECT MIN(CTID) AS RECID, ud.user_id, ud.department_id
      FROM user_department ud GROUP BY ud.user_id, ud.department_id) 
  a);
于 2013-02-22T14:28:47.533 回答
5

通过一个查询级别将其简化:

DELETE FROM table_name
WHERE  ctid NOT IN (
   SELECT min(ctid)
   FROM   table_name
   GROUP  BY $other_columns);

.. 其中重复项由$other_columns.
无需在列表中包含GROUP BY子句中的SELECT列,因此您不需要另一个子查询。

ctid在当前手册中。

于 2013-02-22T15:19:50.057 回答
0

您应该考虑使用row_number()if want to delete 基于唯一的 id 列(或时间戳),因为ctid当您只想保留最近的记录等时,单独使用并不总是可靠的。

WITH d 
     AS (SELECT ctid c, 
                row_number() 
                  OVER ( 
                    partition BY s 
                    ORDER BY id) rn 
         FROM   t) 
DELETE FROM t 
WHERE  ctid IN (SELECT c 
               FROM   d 
               WHERE  rn > 1)  ; 

演示

于 2018-06-10T09:20:15.060 回答