如何通过特定字段行清除数据库中的数据库,以便只留下每组相同行的一个副本?
我有一张桌子:
CREATE TABLE table1 (field1 varchar(255), field2 varchar(255));
我想清除table1
任何不必要的行副本,从每组行中留下一个随机行,并使用相同的field1
。
UPD :请发布与MySQL兼容的命令。
答案 0 :(得分:4)
最简单的方法是使用特定于MySQL的ALTER IGNORE命令。通过创建索引来删除行是不直观的,但效果很好。 IGNORE关键字表示在创建索引时,将删除任何重复的行。并且,将索引保留在我们下面创建的位置将防止将来出现重复。如果您不希望出现这种情况,请在创建索引后删除该索引。
ALTER IGNORE TABLE table1 ADD UNIQUE INDEX indexname (field1, field2)
答案 1 :(得分:1)
在MySQL中:
CREATE TABLE `new_table` LIKE `table1`;
INSERT INTO `new_table` ( SELECT * FROM `table1` GROUP BY field1 );
DROP TABLE `table1`;
RENAME TABLE `new_table` TO `table1`;
这不会完全选择“随机”重复行,但如果你不关心它,它可能会达到你想要的效果。
如果您有更多字段需要与其余字段结合使用,请将它们添加到GROUP BY子句中。
编辑:恢复旧答案
答案 2 :(得分:1)
根据弗拉斯沃斯的回答,我会:
field1
定义为主键主键将停止插入具有相同field1值的行,并且对于以后的查询总体上更好。
答案 3 :(得分:0)
这应该这样做(在SQL Server中未经测试):
SELECT field1, field2
INTO #temp
FROM
(SELECT ROW_NUMBER() OVER (PARTITION BY field1 ORDER BY NEWID()) AS __ROW, *
FROM table1) x
WHERE x.__ROW = 1;
DELETE table1;
INSERT table1
SELECT field1, field2
FROM #temp;
答案 4 :(得分:0)
所以你可以创建一个没有重复的新表。我想你已经想到了这一点。
CREATE TABLE new_test (field1 INTEGER, field2 INTEGER);
INSERT INTO new_test(field1,field2) SELECT DISTINCT field1,field2 FROM test;
DROP TABLE test;
RENAME TABLE new_test test;
如果您有唯一的密钥,则可以通过使用唯一密钥>
来实现自联接并识别目标,而不是最小密钥。如果你没有这样的钥匙,你可以做一个:
ALTER TABLE t2 ADD COLUMN (pk INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY(pk));
无论如何,现在你可以进行自我加入并保持MIN(pk):
mysql> DELETE dups.* FROM t2 AS dups
INNER JOIN (
SELECT field1,field2,MIN(pk) as MPK FROM t2
GROUP BY field1,field2 HAVING COUNT(*) > 1 ) AS keep
ON keep.field1=dups.field1
AND keep.field2=dups.field2
AND keep.MPK <> dups.pk;
答案 5 :(得分:0)
您可以使用MYSQL的ALTER IGNORE语法。以下命令将删除任何重复项,并留下一个随机行:
alter ignore table table1 add unique index index1 (field1);
保持索引到位是明智的,因此无法添加新的重复项。但是如果您愿意,可以使用以下命令删除索引:
alter table table1 drop index index1;