Mysql 在SQL表的多个列上查找重复项以创建唯一索引

Mysql 在SQL表的多个列上查找重复项以创建唯一索引,mysql,sql,indexing,duplicates,duplicate-removal,Mysql,Sql,Indexing,Duplicates,Duplicate Removal,我在一个名为table的表上创建了一个名为abc的索引,该表的主键为id,其他三个INT列a、b和c可以为NULL 现在我需要这个索引是唯一的,所以我尝试: ALTER TABLE table DROP INDEX abc, ADD UNIQUE abc (a, b, c); 但我有重复的,所以MySQL回答: #1062 - Duplicate entry '1-2-3' for key 'abc' 我可能有很多这样的副本,所以我正在寻找一种简单的方法来搜索和销毁它们。我的第一个猜测是:

我在一个名为table的表上创建了一个名为abc的索引,该表的主键为id,其他三个INT列a、b和c可以为NULL

现在我需要这个索引是唯一的,所以我尝试:

ALTER TABLE table DROP INDEX abc, ADD UNIQUE abc (a, b, c);
但我有重复的,所以MySQL回答:

#1062 - Duplicate entry '1-2-3' for key 'abc'
我可能有很多这样的副本,所以我正在寻找一种简单的方法来搜索和销毁它们。我的第一个猜测是:

SELECT * FROM table GROUP BY abc
但遗憾的是,你似乎无法按索引进行分组

有没有一种简单的方法可以找到这些副本,每个副本保留一行,然后删除其他副本

编辑:

表作为主键的id字段 a、 b和c都是INT,可以为NULL 试试这个来找出被骗者

Select a, b, c
From table 
group By a, b, c
Having Count(*) > 1
如果此表中已有唯一的键列,请说明其pkColumn, 您可以这样做来删除额外的重复

Delete table
From table t
Where pkColumn <>
   (Select Min(pkColumn)
    From table
    where a = t.a
      and b = t.b
      and c = t.c)
试试这个来找出被骗者

Select a, b, c
From table 
group By a, b, c
Having Count(*) > 1
如果此表中已有唯一的键列,请说明其pkColumn, 您可以这样做来删除额外的重复

Delete table
From table t
Where pkColumn <>
   (Select Min(pkColumn)
    From table
    where a = t.a
      and b = t.b
      and c = t.c)

我猜你有几张唱片不属于这种情况

避免数据丢失

CREATE table duplicates SELECT MIN(id) as id, a, b, c,  COUNT(1) as nduplicates 
FROM yourtable
GROUP BY a,b,c 
HAVING COUNT(1)>1;

UPDATE yourtable t, duplicates d 
SET t.a='toDelete(or some value that you can easy identify from the rest)' 
WHERE d.a=t.a and d.b=t.b and d.c=t.c 
and d.id!=t.id;

DELETE FROM yourtable WHERE a='toDelete';

然后删除表中的重复项。

我猜您有几个记录不在这种情况下

避免数据丢失

CREATE table duplicates SELECT MIN(id) as id, a, b, c,  COUNT(1) as nduplicates 
FROM yourtable
GROUP BY a,b,c 
HAVING COUNT(1)>1;

UPDATE yourtable t, duplicates d 
SET t.a='toDelete(or some value that you can easy identify from the rest)' 
WHERE d.a=t.a and d.b=t.b and d.c=t.c 
and d.id!=t.id;

DELETE FROM yourtable WHERE a='toDelete';

然后删除重复项表。

无需首先消除重复项,只需使用来完成您想要的操作

ALTER IGNORE TABLE table DROP INDEX abc, ADD UNIQUE abc (a, b, c);

如果未指定IGNORE,则在出现重复密钥错误时中止复制并回滚。如果指定了IGNORE,则在唯一键上具有重复项的行中仅使用一行。其他冲突行将被删除


…在运行来自Internet上随机用户的具有潜在破坏性的SQL之前,请始终记住备份您的数据。

无需首先消除重复项,只需使用来完成您想要的操作

ALTER IGNORE TABLE table DROP INDEX abc, ADD UNIQUE abc (a, b, c);

如果未指定IGNORE,则在出现重复密钥错误时中止复制并回滚。如果指定了IGNORE,则在唯一键上具有重复项的行中仅使用一行。其他冲突行将被删除


…在运行来自Internet上随机用户的具有潜在破坏性的SQL之前,请始终记住备份数据。

这是一个简单而优雅的方法,它将为我节省大量时间。非常感谢。如果所有副本都相等,这是一种简单的方法。如果不是,你需要有一些条件,哪一行最好保留,并使用查询进行删除。这很简单,也很优雅,这将节省我很多时间。非常感谢。如果所有副本都相等,这是一种简单的方法。如果不是这样,您需要有某种条件来保留哪一行更好,并使用查询执行删除。这是查看所有重复项的好方法。我忘了说a、b和c可以是空的,不应该被认为是重复的,但你可以通过添加a`不为空,b不为空,c不为空来解决这个问题。这是查看所有重复项的好方法。我忘了说a、b和c可以为NULL,并且不应该在它们所在的位置被视为重复,但是你可以通过添加a`不为NULL、b不为NULL和c不为NULL的位置来解决这个问题。第一个查询是查看所有重复项的好方法。我忘了说a、b和c可以为NULL,并且不应该在它们所在的位置被认为是重复的,但是你可以通过添加a`不为NULL、b不为NULL和c不为NULL的位置来解决这个问题。我没有尝试第二个查询,因为choosen答案对我来说已经足够好了,但是谢谢。第一个查询是查看所有重复项的好方法。我忘了说a、b和c可以为NULL,并且不应该在它们所在的位置被认为是重复的,但是你可以通过添加a`不为NULL、b不为NULL和c不为NULL的位置来解决这个问题。我没有尝试第二个问题,因为choosen的答案对我来说已经足够好了,但是谢谢。