更新一個字段當好寫
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有更有效的辦法,還望不吝告知。
