使用带有子查询的重复数据删除

chr*_*s85 2 mysql duplication subquery functions

我继承了一个缺乏唯一约束的数据库,因此数据被/被复制。我现在正在尝试删除重复的记录,然后添加一个约束来阻止这一点。

我有这个查询:

SELECT count(*) as dacount, substr(group_concat(id), (locate(',', group_concat(id))+ 1))
FROM `game`
group by matchid, ordinal
having dacount > 1
order by dacount desc
Run Code Online (Sandbox Code Playgroud)

这正确地给了id我需要删除的行的s。但问题是,DELETE由于dacountwithhaving参数,我不能将其用作子查询。有没有另一种方法可以做到这一点?

这是我的计划:

DELETE FROM game WHERE id IN (SELECT count(*) as dacount, substr(group_concat(id), (locate(',', group_concat(id))+ 1))
FROM `game`
GROUP BY matchid, ordinal
HAVING dacount > 1)
Run Code Online (Sandbox Code Playgroud)

ype*_*eᵀᴹ 5

在 MySQL 的UPDATE和实现中有关于自连接的限制DELETE。这个问题通常可以通过使用连接来解决:

DELETE g.*
FROM game AS g
  JOIN 
   ( SELECT matchid, ordinal, min(id) AS id 
     FROM game
     GROUP BY matchid, ordinal
     -- HAVING count(*) > 1
   ) AS d
   ON  g.matchid = d.matchid
   AND g.ordinal = d.ordinal
   AND g.id > d.id ;
Run Code Online (Sandbox Code Playgroud)

dbfiddle.uk测试。


另一种方法是使用LEFT JOIN/IS NULL构造:

DELETE g.*
FROM game AS g
  LEFT JOIN 
   ( SELECT min(id) AS id 
     FROM game
     GROUP BY matchid, ordinal
   ) AS d
   ON  g.id = d.id 
WHERE d.id IS NULL ;
Run Code Online (Sandbox Code Playgroud)

或者将EXISTS子查询重写为JOIN
(删除所有存在相同matchid, ordinal和较小游戏的游戏id):

DELETE g.*
FROM game AS g
  JOIN 
     game AS d
   ON  g.matchid = d.matchid
   AND g.ordinal = d.ordinal
   AND g.id > d.id
 ;
Run Code Online (Sandbox Code Playgroud)