文章插图
步骤一
文章插图
步骤二
文章插图
步骤三
从上面的过程中,我们一步一步定位到了我们需要删除的数据是哪些 。定位到这些数据之后,删除的时候,只要把查询语句改为删除语句即可 。所以最后通过这样的方式来删除我时候,我们的删除语句如下:
delete from user_info where (name,sex,age) in (select x.* from ( -- 删除的时候,这里要在包裹一层子查询select -- 查询重复数据中,name, sex, age的值name, sex, agefrom user_infogroup by name, sex, agehaving count(*) > 1 ) as x)and id not in ( select min_id from ( -- 删除的时候,这里要在包裹一层子查询select -- 查询重复数据中,最小的id值min(id) as min_idfrom user_infogroup by name, sex, agehaving count(*) > 1 ) as y);
注意:上面的删除语句中,我们在两个where条件中的子查询语句外面又包裹了一层子查询,即为上面SQL语句中的as x和as y两个查询语句,之所以包裹一层的原因是在程序如下的错误提示:1093 - You can't specify target table 'user_info' for update in FROM clause, Time: 0.084000s
上述错误的原因是:修改一个表的时候子查询不能是这被修改的这个表,所以,我们的解决办法是,在子查询外面再套一层查询语句就可以了 。方法二上面方法一的思路是想办法找到我们要删除的数据是哪些,然后我们在删除的时候,使用where条件去匹配这些查询出来要删除的数据行,以此来达到删除重复数据的目的 。
文章插图
换个思路解决
此时,我们不妨换一个角度思考:我们不要去关注哪些是我们需要删除的重复数据,相反,我们去关注哪些是我们需要留下来的数据 。然后我们可以在删除的时候,使用取反的方式not in我们需要保留下来的数据,那不是就我们需要删除的数据吗?
所以,我们想一想哪些使我们需要留下来的数据呢?每一组数据中,id值最小的哪一行就是我们要保留的数据行 。其余的我们就不关心了 。那么怎么样才能取到这样的数据行呢?
- 使用下面的SQL语句可以获取我们需要保留的数据行的所有的id的值:
selectmin(id) from user_info group by name, sex, age;
- 结果如下:
文章插图
既然我们想要保留的数据行的id集合得到了,在我们要删除数据的where条件中,使用not in我们要保留的id集合,不就是需要删除的数据吗?
- 删除重复数据的语句如下:
delete from user_info where id not in( select min_id from (selectmin(id) as min_idfrom user_infogroup by name, sex, age ) as x);
注意:这里为了避免MySQL的1903错误,我们也在where条件的子查询中包裹了另外一个子查询,即上面SQL中as x查询语句 。方法三
文章插图
寻找更高效简单的方法
通过两个表关联的方式来删除数据,这个方式效率比较高,推荐使用这种方式 。自己和自己关联,关联的条件就是我们判断数据是否为重复数据的key 。除此之外,最重要的一个条件是:两个表的id关联条件,这个是删除保留数据的关键条件 。
- 查询重复数据的SQL语句如下:
select a.*,b.* from user_info as a inner join user_info as b on a.name = b.name and a.sex = b.sex and a.age = b.ageanda.id > b.id;
- 结果如下:
文章插图
写法1删除重复数据SQL语句如下:
delete a.*from user_info as a inner join user_info as b on a.name = b.name and a.sex = b.sex and a.age = b.ageanda.id > b.id;
写法2除了上面的那种写法之外,还有另外一种写法,如下:查询待删除的重复数据SQL如下:
select * from user_info as a where a.id <> ( selectmin(b.id)from user_info as bwhere a.name = b.name and a.sex = b.sex and a.age = b.age);
删除重复数据的SQL语句如下:delete a.* from user_info as awhere a.id <> ( selectmin(b.id) from (select * from user_info ) as b where a.`name`= b.`name` and a.sex = b.sex and a.age = b.age);
总结以上是对于MySQL中重复数据删除的时候,经常使用的方法 。对于其他数据库中存在的重复数据,删除的思路也是这些,只是具体到SQL语句的写法可能稍有稍有差异 。只要你掌握了思路,具体到SQL语句的写法,尝试几次就可以成功 。
推荐阅读
- 在 JS 中如何使用 Ajax 来进行请求
- 如何设置路由器的防蹭网功能?
- 汉灵帝如何使汉朝灭亡 汉灵帝有多少实权
- 安化松针加工工艺,如何挑选松针茶
- MySQL运行机制
- 白琳工夫属于什么茶,如何区分白琳工夫
- 这些症状证明你傻肠胃炎 冬季如何避免肠胃炎
- 冬季如何让宝宝远离感冒疾病
- 冬季锻炼抗囤脂 如何做好有氧运动
- 冬季呼吸道疾病高发期 该如何预防?