如何在DELETE语句中使用行的物理位置(ROWID)

时间:2013-02-22 14:28:48

标签: sql database postgresql rowid

我有一个包含大量重复行且没有主键的表 我想删除重复的记录,但是当我尝试这样做时,它会删除所有的同行。

如何在Postgres的表格中找到ROWID

3 个答案:

答案 0 :(得分:4)

通过一个查询级别简化此操作:

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

..其中重复项由$other_columns中的相等定义 不需要在GROUP BY列表中包含SELECT子句中的列,因此您不需要其他子查询。

ctid in the current manual.

答案 1 :(得分:3)

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

所以如果你想查看它,请使用这样的QUERY:

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是您要用来过滤它的列。

即:

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);

答案 2 :(得分:0)

如果要根据唯一ID列(或时间戳)删除,则应考虑使用row_number(),因为当您只想保留最近的记录等时,单独ctid并不总是可靠的。 / p>

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)  ; 

Demo