如何通过OID删除记录?

时间:2017-02-26 11:49:52

标签: sql postgresql

我有一个奇怪的案例,我不知道它是怎么发生的。

这是我的表:

id
date
amount

其中id不能为NULL且自动增加。

去年有人制造了以下情况:

OID        id     date    amount
710604512 197 2015-03-11 10657.61
710604513 197 2015-03-11 10657.61

这会导致巨大的问题,因为id应该是唯一的 我无法通过常规SQL修复此问题,因为我将执行的任何操作都将在两行上完成。

其中一个需要删除。

删除和插入一个的解决方案是不可接受的,因为我无法使用日期(它记录创建的日期,日志将显示它)

如何按OID删除行?

3 个答案:

答案 0 :(得分:2)

如果要删除较小 OID的记录,如果发生重复,则可以尝试:

WITH cte AS (
   SELECT *,
          ROW_NUMBER() OVER (PARTITION BY id, date, amount ORDER BY OID DESC) AS rn
   FROM yourTable
) 
DELETE FROM cte WHERE rn=2;     -- or rn >=2 to delete all duplicates

要删除更大 OID的记录,只需将ORDER BY子句更改为:

ORDER BY OID

答案 1 :(得分:1)

假设您希望为每个ID保留具有最大OID的行,您可以使用:

delete 
from your_table t1
    using (
        select id, max(OID)
        from your_table
        group by id
        ) t2
where t1.id = t2.id and t1.OID <> t2.OID;

或者:

delete
from your_table t1
where exists (
    select 1
    from your_table t2
    where t1.id = t2.id
    and t1.OID < t2.OID
);

答案 2 :(得分:1)

如果id, date, amount是您案例中的业务键,则可以通过按这些列进行分组来删除超过秒的所有记录。像这样:

DELETE FROM theTable
WHERE OID IN (
    SELECT OID 
    FROM (  SELECT ROW_NUMBER() OVER (PARTITION BY id, date, amount) AS RowNo, OID 
            FROM tab) x 
    WHERE x.RowNo > 1);

注意:无论重复次数多少,这都应该有效。