MySQL的update理解,批量更新问题: 同一张表中根据某个字段与另一个字段值,更新第三个字段

一直写select语句, 很少写复杂的update语句,

最近我想批量更新一个表,要求是更新每条数据的a字段,具体更新的值是这条数据的id字段在b字段中出现的次数.简单的理解为下图:

    表: abc

《MySQL的update理解,批量更新问题: 同一张表中根据某个字段与另一个字段值,更新第三个字段》

把count字段更新为其id在f_id中出现的次数,update完成后应该是:

    表:abc

《MySQL的update理解,批量更新问题: 同一张表中根据某个字段与另一个字段值,更新第三个字段》

即id为1的count值是2,因为1在f_id中出现了2次; id为2的count值是3,因为2在f_id中出现了3次;

我刚开始的解决思路是这样的:

  

 update abc a1 set count = ( 

                                            select co from (

                                                                    select count(*) from abc a2 where a1.id = a2.f_id

                                                                        ) aa

                                                )

但是它会报错, 说不认识a1.id : 

        Unknown column ‘a1.id’ in ‘where clause’

看他的错误信息意思好像是a1.id 不能出现在where从句里,那我在where之前去用好不好呢?

然后我就这样去写:

    update abc a1 set count = (

                                                  select co from (

 

                                                                                select sum(case a1.id when a2.f_id then 1 else 0 end) co from abc a2

                                                                               ) aa

                                                 )     

我还是太天真啊…   还是报错: Unknown column ‘a1.id’ in ‘field list’ 

然后我问了朋友才知道,  我们要用select查询造的虚拟表当做查询源的时候, 这个select语句是完全独立的, 不和他以外的SQL相通,所以就不认识定义的别名a1了.

    好吧,明确知道这条路走不通了之后,我陷入深深的绝望,然后搜索相关批量更新的帖子,发现有人用这种方法:

        update  表1  a1  inner join  (select 字段1,字段2 from 表1 where 条件) a2 on 条件

        set   a1.字段1 = a2.字段2 

    哇,这个思路厉害了啊  先造出来一个虚拟表,然后通过更新虚拟表的方式去实现具体的更新;

     然后我就这样去写:

update abc a inner join  (select f_id, count(*) co from abc group by f_id) b on  a.id = b.f_id 
set a.count = b.co
内连接出来的虚拟表是:

abc表:
a.id   a.f_id  a.count
1      0        0
2      1        0
3      1        0
4      2        0
6      2        0

 

7      2        0

 

    +

查询结果:
b.f_id  b.co 
  0       1
  1       2

  2       3

    =

虚拟表:

a.id    a.f_id    a.count     b.f_id         b.co 

1           0           0               1              2
2           1           0               2              3

然后set    a.count = b.co  就ok了  

虽然是操作的虚拟表,但是能影响到具体的实体表啊!!  

不知道是不是我太孤落寡闻了… 对于这种操作真的是想不到啊.

 

好了,再看下这个sql:

 

  update 

        abc a 

  inner join 

      (select f_id, count(*) as co from abc group by f_id) b
  on 
      a.id = b.f_id 
  set 

      a.count = b.co

我们也换一下用左联接

(更新的是虚拟表左边的字段,左联接可以保证虚拟表左边的字段都有实体表字段相对应,不至于set的对象是个null,set的值是个null不怕,但是把一个值set给null就有问题了):

  update 

        abc a 

  left join 

      (select f_id, count(*) as co from abc group by f_id) b
  on 
      a.id = b.f_id 
  set 

      a.count = ifnull(b.co,0)    /*左联接有可能右边没有对应的值, 当没有时设置为0)*/

记下来,加强一下印象,也希望能帮助到新手朋友;

 

    原文作者:qq_37709240
    原文地址: https://blog.csdn.net/qq_37709240/article/details/80049744
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞