如何基于多个字段删除SQL表中的重复项

时间:2011-06-24 17:25:44

标签: mysql sql duplicate-removal

我有一张游戏表,描述如下:

+---------------+-------------+------+-----+---------+----------------+
| Field         | Type        | Null | Key | Default | Extra          |
+---------------+-------------+------+-----+---------+----------------+
| id            | int(11)     | NO   | PRI | NULL    | auto_increment |
| date          | date        | NO   |     | NULL    |                |
| time          | time        | NO   |     | NULL    |                |
| hometeam_id   | int(11)     | NO   | MUL | NULL    |                |
| awayteam_id   | int(11)     | NO   | MUL | NULL    |                |
| locationcity  | varchar(30) | NO   |     | NULL    |                |
| locationstate | varchar(20) | NO   |     | NULL    |                |
+---------------+-------------+------+-----+---------+----------------+

但是每个游戏在某个地方的表格中都有重复的条目,因为每个游戏都在两个团队的日程表中。是否有一个sql语句我可以用来查看并根据相同的日期,时间,hometeam_id,awayteam_id,locationcity和locationstate字段删除所有重复项?

9 个答案:

答案 0 :(得分:45)

您应该能够执行相关子查询来删除数据。找到所有重复的行并删除除id之外的所有行。对于MYSQL,需要使用内连接(功能等同于EXISTS),如下所示:

delete games from games inner join 
    (select  min(id) minid, date, time,
             hometeam_id, awayteam_id, locationcity, locationstate
     from games 
     group by date, time, hometeam_id, 
              awayteam_id, locationcity, locationstate
     having count(1) > 1) as duplicates
   on (duplicates.date = games.date
   and duplicates.time = games.time
   and duplicates.hometeam_id = games.hometeam_id
   and duplicates.awayteam_id = games.awayteam_id
   and duplicates.locationcity = games.locationcity
   and duplicates.locationstate = games.locationstate
   and duplicates.minid <> games.id)

要进行测试,请将delete games from games替换为select * from games。不要只在数据库上运行删除: - )

答案 1 :(得分:13)

您可以尝试这样的查询:

DELETE FROM table_name AS t1
WHERE EXISTS (
 SELECT 1 FROM table_name AS t2 
 WHERE t2.date = t1.date 
 AND t2.time = t1.time 
 AND t2.hometeam_id = t1.hometeam_id 
 AND t2.awayteam_id = t1.awayteam_id 
 AND t2.locationcity = t1.locationcity 
 AND t2.id > t1.id )

这将在数据库中仅留下具有最​​小id的每个游戏实例的一个示例。

答案 2 :(得分:7)

对我有用的最好的事情是重新创建表格。

CREATE TABLE newtable SELECT * FROM oldtable GROUP BY field1,field2;

然后您可以重命名。

答案 3 :(得分:5)

获取与两个字段匹配的重复条目列表

select t.ID, t.field1, t.field2
from (
  select field1, field2
  from table_name
  group by field1, field2
  having count(*) > 1) x, table_name t
where x.field1 = t.field1 and x.field2 = t.field2
order by t.field1, t.field2

并删除所有重复

DELETE x 
FROM table_name x
JOIN table_name y
ON y.field1= x.field1
AND y.field2 = x.field2
AND y.id < x.id;

答案 4 :(得分:4)

select orig.id,
       dupl.id
from   games   orig, 
       games   dupl
where  orig.date   =    dupl.date
and    orig.time   =    dupl.time
and    orig.hometeam_id = dupl.hometeam_id
and    orig. awayteam_id = dupl.awayeam_id
and    orig.locationcity = dupl.locationcity
and    orig.locationstate = dupl.locationstate
and    orig.id     <    dupl.id

这应该给你重复;您可以将其用作子查询来指定要删除的ID。

答案 5 :(得分:2)

只要您没有在选择查询中获取表格的ID(主键),而其他数据完全相同,您就可以使用SELECT DISTINCT来避免重复结果。

答案 6 :(得分:2)

delete from games 
   where id not in 
   (select max(id)  from games 
    group by date, time, hometeam_id, awayteam_id, locationcity, locationstate 
    );

解决方法

select max(id)  id from games 
    group by date, time, hometeam_id, awayteam_id, locationcity, locationstate
into table temp_table;

delete from games where id in (select id from temp);

答案 7 :(得分:1)

DELETE FROM table
WHERE id = 
    (SELECT t.id
    FROM table as t
    JOIN (table as tj ON (t.date = tj.data
                          AND t.hometeam_id = tj.hometeam_id
                          AND t.awayteam_id = tj.awayteam_id
                          ...))

答案 8 :(得分:1)

DELETE FROM tbl
 USING tbl, tbl t2
 WHERE tbl.id > t2.id
  AND t2.field = tbl.field;

在您的情况下:

DELETE FROM games
 USING games tbl, games t2
 WHERE tbl.id > t2.id
  AND t2.date = tbl.date
  AND t2.time = tbl.time
  AND t2.hometeam_id = tbl.hometeam_id
  AND t2.awayteam_id = tbl.awayteam_id
  AND t2.locationcity = tbl.locationcity
  AND t2.locationstate = tbl.locationstate;

参考:https://dev.mysql.com/doc/refman/5.7/en/delete.html