25

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

+---------------+-------------+------+-----+---------+----------------+
| 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 字段的所有重复项?

4

9 回答 9

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 gamesselect * from games. 不要只是在您的数据库上运行删除:-)

于 2011-06-24T17:36:17.830 回答
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 的游戏实例的一个示例。

于 2011-06-24T17:41:31.700 回答
8

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

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

然后,您可以重命名。

于 2016-12-02T15:06:12.407 回答
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;
于 2014-03-25T08:39:58.617 回答
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。

于 2011-06-24T17:36:44.903 回答
3

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

于 2011-06-24T17:32:25.453 回答
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);
于 2011-06-24T17:47:45.043 回答
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
                          ...))
于 2011-06-24T17:42:43.157 回答
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

于 2020-07-08T07:28:24.203 回答