mysql查重处理问题

碰巧今天需要对数据库中某个字段进行查重,并对重复的记录进行操作,于是上网查找了关于mysql数据库查重的语句,查了很多,给出的结果都是
SELECT j1.id FROM jokes j1 WHERE j1.content IN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1)

这里content是jokes表中的一个非主键字段。

然而坑人的事情就这样发生,这条语句运行起来,简直慢的令人发指,全程没有耐心等待,这都查询不出结果,跟不用说修改和删除操作了。下面是这个语句查询的用时结果:

SELECT j1.id FROM jokes j1
 WHERE j1.content IN (SELECT content FROM jokes WHERE content !='' GROUP BY content HAVING COUNT(content) > 1)
执行:8 min 27 sec     总数:8 min 27 sec    630行

8分半,这是多久的时间啊,仅仅一条查询语句居然需要这么久的时间,可见效率是有多么的低。

于是我又想到了建立临时表的方法查询:

CREATE TABLE jokes_bak AS (
SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1
)
建立临时表以后,进行查询:

SELECT id FROM jokes
 WHERE content IN (
SELECT content FROM jokes_bak)
执行:0.252 sec     总数:0.253 sec    630行
这个结果总算感觉正常了,那么接下来皆可以进行一系列的修改删除操作了,如:

修改操作:update jokes set content = 'chongfu' where content in ( SELECT content FROM jokes_bak)

共 630 行受到影响
执行耗时   : 1.545 sec
传送时间   : 0 sec
总耗时      : 1.546 sec

删除操作类似,其中,删除多余重复,留下id最小一条记录的操作为:

DELETE FROM jokes WHERE content IN 
(SELECT content FROM jokes_bak) AND id NOT IN 
(SELECT MIN(id) FROM jokes
 WHERE content IN (
SELECT content FROM jokes_bak) GROUP BY content)
通过搜索资料和尝试,发现还可以 使用inner join来查询,查询结果如下:

SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes WHERE content !='' GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content)

执行:0.384 sec     总数:0.386 sec    630行

显然时间比第一种in的方式快的多,而事实上mysql中in、like应该尽量少用,第一种语句慢的另一个原因是因为没有建立索引。

那么这里还有另外一个问题,使用inner join的好处显而易见,不用额外建立一个临时表,但是进行修改删除操作的时候就出问题了,我使用一下语句进行修改:

UPDATE jokes SET SUBJECT = 'chongfu' WHERE id IN (
SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content))

提示错误:

错误代码: 1093

You can't specify target table 'jokes' for update in FROM clause

这个错误应该是mysql禁止对同一个表进行嵌套修改,防止一些错误的产生,这里解决这个问题的方法是,嵌套一层表查询,给表起个别名:

UPDATE jokes SET content='重复段子' WHERE id IN(
SELECT jd.id FROM(
SELECT j1.id FROM jokes j1
INNER JOIN (SELECT content FROM jokes GROUP BY content HAVING COUNT(content) > 1) AS j2 USING(content)
) jd)





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值