【问题标题】:Delete duplicate rows from table从表中删除重复的行
【发布时间】:2011-05-07 12:52:01
【问题描述】:

我的表中有唯一键 id 键,但我有一列包含重复值?我如何摆脱这些,同时像这样只保留其中一个:

重复记录:

id  | name   | surname |
1   | test   | one     |
2   | test   | two     |
3   | test3  | three   |
4   | test7  | four    |
5   | test   | five    |
6   | test11 | eleven  |

没有重复:

id  | name   | surname |
1   | test   | one     |
3   | test3  | three   |
4   | test7  | four    |
6   | test11 | eleven  |

我已经用谷歌搜索了这个,但它似乎不起作用:

DELETE  ct1
FROM    mytable ct1
        , mytable ct2
WHERE   ct1.name = ct2.name 
        AND ct1.id < ct2.id 

ERROR:  syntax error at or near "ct1"
LINE 1: DELETE  ct1
                ^

********** Error **********

我正在使用 postgres 数据库。

【问题讨论】:

  • 清理完数据后,您可能需要对“名称”设置唯一约束。

标签: sql postgresql


【解决方案1】:

您可以尝试此运行多次

delete from mytable where id in (
    select max(id)
      from mytable
     group by name
    having count(1) > 1
);

其中 multiple times 等于您在name 列中的最大重复次数。

否则,您可以尝试这个更复杂的查询:

delete from mytable where id in (
    select id from mytable
    except 
    (
    select min(id)
      from mytable
     group by name
    having count(1) > 1
    union all
    select min(id)
      from mytable
     group by name
    having count(1) = 1
    )
);

仅运行一次此查询应该会删除您需要的所有内容。不过没试过……

【讨论】:

  • 很高兴它有帮助。对于这样的复杂分组,我建议您学习window functions,例如Rank @Dalen 在其他答案中建议。他们值得学习。
【解决方案2】:

使用Rank,实际上我不太确定语法,因为我不太擅长 PostgreSQL,这只是一个提示(任何人的更正将不胜感激):

DELETE FROM mytable
WHERE id NOT IN
(
   SELECT x.id FROM
   (
      SELECT id, RANK() OVER (PARTITION BY name ORDER BY id ASC) AS r
      FROM mytable
   ) x
   WHERE x.r = 1
)

【讨论】:

    猜你喜欢
    • 2012-10-21
    • 2010-11-05
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多