• mysql 多字段更新


    更新一个字段当好写

    update user set collect_num=(select sum(collect_num) from article where user_id=user.id) where user.id=1;
    Query OK, 0 rows affected (17.36 sec)
    Rows matched: 1 Changed: 0 Warnings: 0

    问题是想更新多个字段
    sql server 支持下面这种语法

    update user set (article_num,collect_num,like_num)=(select count(*),sum(collect_num),sum(like_num) from article where user_id=user.id) where user.id=1;

    试过并查官网后,发现mysql并不支持

    先用最笨的办法

    update user set 
    article_num=(select count(*) from article where user_id=user.id),
    collect_num=(select sum(collect_num) from article where user_id=user.id),
    like_num=(select sum(collect_num) from article where user_id=user.id) 
    where user.id=1;
    Query OK, 1 row affected (54.79 sec)
    Rows matched: 1  Changed: 1  Warnings: 0

    时间居然是更新一个字段的的3倍,可能是查了三次article表,验证确实如此

    mysql> explain select  (select count(*) from article where user_id=1),(select sum(collect_num) from article where user_id=1),(select sum(collect_num) from article where user_id=1);
    +----+-------------+---------+-------+------------------------------+------------------------------+---------+------+---------+--------------------------+
    | id | select_type | table   | type  | possible_keys                | key                          | key_len | ref  | rows    | Extra                    |
    +----+-------------+---------+-------+------------------------------+------------------------------+---------+------+---------+--------------------------+
    |  1 | PRIMARY     | NULL    | NULL  | NULL                         | NULL                         | NULL    | NULL |    NULL | No tables used           |
    |  4 | SUBQUERY    | article | index | user_id_like_num_collect_num | user_id_like_num_collect_num | 104     | NULL | 3047331 | Using where; Using index |
    |  3 | SUBQUERY    | article | index | user_id_like_num_collect_num | user_id_like_num_collect_num | 104     | NULL | 3047331 | Using where; Using index |
    |  2 | SUBQUERY    | article | index | user_id_like_num_collect_num | user_id_like_num_collect_num | 104     | NULL | 3047331 | Using where; Using index |
    +----+-------------+---------+-------+------------------------------+------------------------------+---------+------+---------+--------------------------+

    不能忍

    能想到的办法就是起临时表(或外部写代码,python什么的,实现类似临时表的功能)了,毕竟临时表万能。

    但还是想在sql层面解决

    update user u 
    JOIN (select user_id as user_id,count(*) as article_num,sum(collect_num) as collect_num,sum(like_num) as like_num from article where user_id=1) t 
    on u.id=t.user_id 
    set u.article_num=t.article_num,u.collect_num=t.collect_num,u.like_num=t.like_num 
    where u.id=1;

    虽然代码不如sqlserver 漂亮,需要改两个值,不过达到目的了,时间并不比单字段耗时。

    更改为单查询条件

    update user u 
    JOIN (select user_id as user_id,count(*) as article_num,sum(collect_num) as collect_num,sum(like_num) as like_num 
    from article 
    group by user_id) t
     on u.id=t.user_id  
    set u.article_num=t.article_num,u.collect_num=t.collect_num,u.like_num=t.like_num  where u.id=101;

    总算差不多了

    个人最熟悉sqlserver,mysql只是顺带打酱油的,如果mysql有更有效的办法,还望不吝告知。

  • 相关阅读:
    逆向分析实战
    打印工程内所有方法的调用
    JAVA B/S系统实现客户端屏幕截图,Java版的QQ截图
    让input支持 ctrl v上传粘贴图片? 让input支持QQ截图或剪切板中的图像数据(Java实现保存)
    spring4 security 4 +websocket 实现单点登录
    Spring quartz 单机、集群+websocket集群实现文本、图片、声音、文件下载及推送、接收及显示
    spring 4.2.0后jdbcTemplate中不用queryForLong了(之系统升级发现)
    友好解决POI导入Excel文件行是不是为空
    解决POI读取Excel如何判断行是不是为空
    集群: 如何在spring 任务中 获得集群中的一个web 容器的端口号?
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/6733783.html
Copyright © 2020-2023  润新知