确实提出了类似的问题,但我没有找到答案。
我有一个包含3个非唯一字段的MySql表。我不想要重复的行。含义("a", "b", "c")
和("a", "dasd", "dfsd")
是可以的(我不介意在第一个字段中有两次“a”),但是("a", "b", "c")
两次是错误的。
我需要一个查询来删除重复项,每个行组只留一行。
答案 0 :(得分:3)
修改这已在SO before。
中涵盖一种方法是基于现有表创建新表。你可以通过以下方式做到这一点:
create table myNewTable SELECT distinct * FROM myOldTable;
然后你可以清除旧表的数据,并在你不想复制的字段上创建一个唯一的约束:
TRUNCATE TABLE myOldTable;
ALTER TABLE myOldTable
ADD UNIQUE (field1, field2);
然后将数据插回原始表格。由于您使用myNewTable
创建了DISTINCT
,因此不应该有任何重复项。
INSERT INTO myOldTable SELECT * FROM myNewTable;
答案 1 :(得分:1)
注意:它假设我们除了column1和column2以及column3之外还有主键。此外,它假定应保留最后一行。除了column1,column2和column3之外我们还有其他一些信息 它保存最后一个主键,并删除其余的Column1,Column2,Column3
的唯一值将以下查询的结果插入临时表
SELECT MAX(PrimaryKey)
FROM TABLENAME
GROUP BY Column1,Column2,Column3
从TABLENAME中删除PrimaryKey NOT IN(SELECT PrimaryKey FROM TEMPTABLE)
如果我们只有这3列,那么
答案 2 :(得分:0)
您可以检索重复项列表,如下所示:
SELECT field1, field2, field3, count(*) AS cnt
FROM yourtable
GROUP by field1, field2, field3
HAVING (cnt > 1)
然后,您必须删除后续单独查询中的重复行。
答案 3 :(得分:0)
我将通过使用临时表和子查询来查找要擦除的元素来解决问题。只有当您的表'yourTable'与字段f1,f2,f3也具有唯一的ID字段时,这才有效。
创建临时表以存储要擦除的元素的ID。
CREATE TEMPORARY TABLE ids (ID int);
找到要删除的元素的ID:
INSERT INTO ids(ID) SELECT ID FROM yourTable AS t
WHERE 1 != (SELECT COUNT(*) FROM yourTable
WHERE yourTable.ID <= t.ID
AND yourTable.f1 = t.f1
AND yourTable.f2 = t.f2
AND yourTable.f3 = t.f3);
使用先前选择的索引
删除表格的元素DELETE yourTable FROM yourTable,ids WHERE yourTable.ID = ids.ID;
删除临时表
DROP TABLE ids;
如果使用相同的表为SELECT和DELETE支持SQL子查询,我们可以在同一个查询中执行所有操作,但事实并非如此,所以我们需要通过一个临时表。
要重复发生重复,我会将这三个字段设置为表格的主键,这样:
ALTER TABLE yourTable ADD PRIMARY KEY (f1, f2, f3);
只有在删除了所有重复项后,您才能以这种方式更改表格,一旦表格发生变化,后续的重复值插入将失败。