V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
sw1962
V2EX  ›  MySQL

MYsql 去重复语句 分析

  •  
  •   sw1962 · 2016-09-30 09:49:29 +08:00 · 3944 次点击
    这是一个创建于 3007 天前的主题,其中的信息可能已经有所发展或是发生改变。
    方法一

    delete from `xxx` where id in (select * from (SELECT min(id) FROM `xxx` group by mail having count(mail)>1) as a);
    这是百度文章里 提到的最多的的一条语句。 240W 的数据处理了 3 个多小时才删除了 19w 数据。

    方法二

    create table tmp_xxx select min(id) as id,mail,password from xxx group by mail,password;
    同样的 240w 数据去重不到两分钟就搞定了。( 160w spend 56s )



    这个方法二,语句,我的 table 是 xs,为什么以下代码会提示错误

    create xs tmp_xxx select min(id) as id,mail,password from xs group by mail,password;
    17 条回复    2016-10-22 18:09:27 +08:00
    GGGG430
        1
    GGGG430  
       2016-09-30 09:58:07 +08:00
    where id in (select * 这条语句能执行?
    wangxkww
        2
    wangxkww  
       2016-09-30 10:09:15 +08:00
    create xs 是什么鬼…… 不应该是 create table 么……
    xss
        3
    xss  
       2016-09-30 10:32:30 +08:00
    这个我能笑一天....create table 是语句要求,tmp_xxx 才是表名.....你这应该写 create table xs 吧....
    2014CD2014
        4
    2014CD2014  
       2016-09-30 10:35:02 +08:00
    逗比么
    wudanyang
        5
    wudanyang  
       2016-09-30 10:35:06 +08:00
    无力吐槽
    coderluan
        6
    coderluan  
       2016-09-30 10:38:30 +08:00
    楼主还是确保之前的知识掌握了再往后看的好。
    phpdever
        7
    phpdever  
       2016-09-30 11:47:32 +08:00
    楼上的都错了,楼主这是 mysql 最新版的写法,哈哈哈哈哈哈
    ethancheung1990
        8
    ethancheung1990  
       2016-09-30 16:10:23 +08:00
    直接用 delete , in 语句用 left join 的方法来代替
    bwangel
        9
    bwangel  
       2016-09-30 16:15:32 +08:00
    @GGGG430

    这个语句是可以执行的,但是两个表不能是相同的表。如果相同的表会报这种错误:

    ERROR 1093 (HY000): You can't specify target table 'test' for update in FROM clause

    参考这里: https://dev.mysql.com/doc/refman/5.7/en/expressions.html

    关于谓词(predicate)的部分。
    ethancheung1990
        10
    ethancheung1990  
       2016-09-30 16:47:42 +08:00
    DELETE T FROM MYTABLE T LEFT JOIN (SELECT MAX(A.ID) AS ID FROM MYTABLE A GROUP BY A.MAIL) TT ON T.ID = TT.ID WHERE TT.ID IS NULL
    ethancheung1990
        11
    ethancheung1990  
       2016-09-30 16:50:48 +08:00
    这个是重复数据只保留一条的语句,如果只删除重复数据里面的一条数据,适当修改
    bwangel
        12
    bwangel  
       2016-09-30 17:05:38 +08:00
    @GGGG430

    闲着蛋疼,又做了一个 Delete SQL 语句的分析。
    bwangel
        13
    bwangel  
       2016-09-30 17:05:51 +08:00
    petelin
        14
    petelin  
       2016-10-01 11:30:13 +08:00
    @ethancheung1990 你这是错的啊,楼主第一种方法只能删除重复里最小的,你这个直接把不重复的也删掉了
    ethancheung1990
        15
    ethancheung1990  
       2016-10-12 12:15:42 +08:00
    @petelin 我这是把重复的删除来只剩一条,不重复的没有删掉 你可以试试。。。
    ethancheung1990
        16
    ethancheung1990  
       2016-10-12 12:22:00 +08:00
    @petelin 如果要按照楼主第一种的需求来删除 那就是
    DELETE T FROM MYTABLE T LEFT JOIN (SELECT MIN(A.ID) AS ID FROM MYTABLE A GROUP BY A.MAIL HAVING COUNT(A.MAIL) > 1) TT ON T.ID = TT.ID WHERE TT.ID IS NOT NULL
    两种需求,一种是只保留一条不重复数据,另一种是删除重复数据中的一条,两种都并没有删除非重复的数据
    mingyun
        17
    mingyun  
       2016-10-22 18:09:27 +08:00
    @ethancheung1990 厉害了我的哥
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1055 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:06 · PVG 04:06 · LAX 12:06 · JFK 15:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.