删除MySQL上的重复行(至少留下一行)

时间:2011-12-08 03:40:35

标签: mysql sql duplicate-removal delete-row

我在MySQL中有这个表:

  • id_word
  • lang_original(原始单词中的语言) VARCHAR(2)
  • lang_target(翻译后的字词) VARCHAR(2)
  • 字(单词本身) VARCHAR(50)
  • 翻译(翻译) VARCHAR(50)

他们不应该有重复。是否有可能找到重复的SQL查询并删除它们(保留第一个匹配未删除)?

更新副本将具有相同的lang_original,lang_target和word(仅限3个字段)。

3 个答案:

答案 0 :(得分:1)

可以像这样工作:

DELETE FROM tbl
WHERE  EXISTS (
   SELECT *
   FROM   tbl t
   WHERE (t.lang_original,   t.lang_target,   t.word)
       = (tbl.lang_original, tbl.lang_target, tbl.word)
   AND tbl.id_word > t.id_word
   )

如果@Jason是对的,并且MySQL不允许引用删除表,那么这是另一种独立运行的表单:

DELETE FROM tbl
USING (
   SELECT min(id_word) AS min_id, lang_original, lang_target, word
   FROM   tbl t
   GROUP  BY lang_original, lang_target, word
   HAVING count(*) > 1
   ) x
WHERE (tbl.lang_original, tbl.lang_target, tbl.word)
   =  (  x.lang_original,   x.lang_target,   x.word)
AND    tbl.id_word > x.min_id

两种变体都会将具有最小id的副本保留为活着并杀死其余部分。

如果您希望首先将所有翻译保存到一组dupes中id最小的单词:

UPDATE tbl SET translation = all_trans
FROM  (
   SELECT min(id_word) AS min_id, group_concat(translation) AS all_trans
   FROM   tbl
   GROUP  BY lang_original, lang_target, word
   HAVING count(*) > 1
   ) t
WHERE  tbl.id_word = t.min_id

答案 1 :(得分:1)

创建新表格更简单。以前的答案很好,但我喜欢这样: 使用" lang_original,lang_target,word"

的唯一键创建一个新表
CREATE TABLE new_table_can_be_renamed_later ( 
  ..your-fields...
  UNIQUE unique (lang_original,lang_target,workd)
);

然后通过选择旧表填充新表并在INSERT中使用 IGNORE

INSERT IGNORE INTO new_table_can_be_renamed_later 
  SELECT * FROM original_table

请考虑Mysql文档以获得正确的语法。

答案 2 :(得分:0)

我不确定你能做到这一点。 你可能最好做一些像

这样的事情
select distinct * into yournewtable from originaltable

这可能有用。