更新一个字段当好写

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有更有效的办法,还望不吝告知。

mysql 多字段更新的更多相关文章

  1. EFCore+Mysql仓储层建设(分页、多字段排序、部分字段更新)

    前沿 园子里已有挺多博文介绍了EFCore+Mysql/MSSql如何进行使用,但实际开发不会把EF层放在Web层混合起来,需要多个项目配合结构清晰的进行分层工作,本文根据个人实践经验总结将各个项目进 ...

  2. 如何使用MySQL一个表中的字段更新另一个表中字段

    [本文出自:https://www.jb51.net/article/150323.htm] 这篇文章主要介绍了如何使用MySQL一个表中的字段更新另一个表中字段,需要的朋友可以参考下 1,修改1列 ...

  3. Mysql跨表更新 多表update sql语句总结

    Mysql跨表更新一直是大家所关心的话题,本文介绍mysql多表 update在实践中几种不同的写法 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是P ...

  4. Mysql跨表更新

    Mysql跨表更新一直是大家所关心的话题,本文介绍mysql多表 update在实践中几种不同的写法,需要的朋友可以参考下 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Pr ...

  5. MySQL时间字段究竟使用INT还是DateTime

    今天解析DEDECMS时发现deder的MYSQL时间字段,都是用 `senddata` ) unsigned '; 随后又在网上找到这篇文章,看来如果时间字段有参与运算,用int更好,一来检索时不用 ...

  6. mysql——插入、更新、删除数据(概念)

    一.插入数据 1.为表的所有字段插入数据 -------------------------------------------------------------------------- (1)i ...

  7. 【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象

    在实际更新Mongo对象时发现,原有的更新代码无法更新复杂的数据类型对象.恰好看到张占岭老师有对该方法做相关的改进,因此全抄了下来. 总的核心思想就是运用反射与递归,对对象属性一层一层挖掘下去,循环创 ...

  8. mysql text字段判断是否为空

    mysql text字段判断是否为空 mysql text字段为空select * from `tableName` where `textField` is null or `textField` ...

  9. 修改MySQL中字段的类型和长度

    MySQL修改字段类型的命令是: mysql> alter table 表名 modify column 字段名 类型; 假设在MySQL中有一个表为:address,有一个字段为city 初始 ...

随机推荐

  1. Java并发分析—synchronized

    在计算机操作系统中,并发在宏观上是指在同一时间段内,同时有多道程序在运行. 一个程序可以对应一个进程或多个进程,进程有独立的存储空间.一个进程包含一个或多个线程.线程堆空间是共享的,栈空间是私有的.同 ...

  2. java8+tomcate8仅支持TLSv1.2

    1.编辑$tomcat_home/conf/server.xml <Connector protocol="org.apache.coyote.http11.Http11NioProt ...

  3. 201412-2 Z字形扫描 Java

    思路: 观察输出可以发现,可以不用定义 "方向" ,看斜线,如果是第偶数条(0也是偶数),从左下到右上输出.如果是第奇数条,从右上到左下输出. import java.util.S ...

  4. 14 微服务电商【黑马乐优商城】:day01-springboot(理论篇)

    本项目的笔记和资料的Download,请点击这一句话自行获取. day01-springboot(理论篇) :day01-springboot(实践篇) :day01-springboot(Thyme ...

  5. 蓝屏(BSOD)转储设置,看本文就够了!

    原总结注册表debug调试dump转储文件蓝屏BSODprocess monitor 前言 我们在 内核转储,开抓啦! 这篇文章里介绍了一个关键的系统设置.设置好后可以让系统在蓝屏(Blue Scre ...

  6. Codeforces620E New Year Tree

    挺好的一道题 Description link 给一棵树,每个点有颜色 \(c_i\) 为点权,需要实现以下两种操作: 子树修改颜色(覆盖),查询子树颜色种类 \(n \leq 4 \times 10 ...

  7. Postgresql的导表

    背景 前面已经介绍了常用的备份与恢复了,接下来介绍一下导表. 正文 很多情况,会有把数据导出的需求,轻重缓急总会有特别紧急的情况,但是又不是专业干db的人,还是记录下来,以防不时之需. 针对于导表,个 ...

  8. POJ 1O17 Packets [贪心]

    Packets Description A factory produces products packed in square packets of the same height h and of ...

  9. 14 微服务电商【黑马乐优商城】:day04-项目搭建(二)

    本项目的笔记和资料的Download,请点击这一句话自行获取. day01-springboot(理论篇) :day01-springboot(实践篇) day02-springcloud(理论篇一) ...

  10. windowsserver的应用升级部署坑

    jar文件的后缀名要打开显示,否者备份的‘.bak20190820’可能后面还是jar可执行文件,以至于mybatis这类xml映射器的namespace方法重复扫上去导致注册tomcat conte ...