写点什么

【MySql 实战】以 sql 的方式多表联动更新数据

作者:安逸的咸鱼
  • 2022 年 7 月 20 日
  • 本文字数:1606 字

    阅读完需:约 5 分钟

【MySql 实战】以 sql 的方式多表联动更新数据

用通俗的话来说,即一个更新操作,需要使用关联的表中的数据,来更新目标表。


按照使用的习惯,不管是在 navicat 或者是 java 后台,都需要拆分为起码 2 条 sql 进行操作。

因这类需求为偶尔在 DB 中执行操作,不可能每次都去把后台跑起来;也不可能每次手工查询目标数据,再修改 update 语句去执行

表结构

一个分类表 mdm_classification,其中,会使用字段 parent 套娃自己组合成 一级、二级、三级分类 的数据映射,对应分类的 code 的长度分别为 2 位、4 位、7 位,其中的命名风格为:aa, aabb, aabbccc,即可以通过具体的三级 code 截取获得 一、二级 的 code


一个物料表 mdm_basics,会有自己唯一的 code,并且,通过 mdm_classification_id 绑定自己归属的三级分类,并且有冗余的字段 mdm_product_code1, mdm_product_code2, mdm_product_code3 来再次绑定自己对应的 一、二、三级分类 对应的 codename

场景

先有的一个 code=1 的物料,他绑定的 三级分类的 code1301001,需要切换为 2302001,这个时候,此物料所属的 一级、二级 分类数据也需要同步维护。

常规的解决方案

需要一个后台,对 2302001 做截取拿到的 一、二级分类的 code,去 DB 查询获得 code 对应的分类记录数据,拼接 update sql 后去 DB 执行,数据更新入库

sql 解决方案

对分类表自连接补全数据

通过 左连接 的方式,为我们需要查询的三级分类的记录,补全对应的 一二级分类的 code、name


SELECT        c3.id c3id,        c1.mdm_code c1code,        c1.mdm_name c1name,        c2.mdm_code c2code,        c2.mdm_name c2name,        c3.mdm_code c3code,        c3.mdm_name c3nameFROM        mdm_classification c3        LEFT JOIN mdm_classification c2 ON c2.mdm_code = left(c3.mdm_code,4)        LEFT JOIN mdm_classification c1 ON c1.mdm_code = left(c3.mdm_code,2)WHERE        c3.mdm_code = '2302001' 
复制代码


联表查询后的效果如下



返回的结果记录中,已经具备有我们需要的全部数据了

联表更新

联表更新的模版如下所示:


UPDATE     tab1 a,    tab2 bSET    a.xx = b.xx [, ...][WHERE conditions...]
复制代码


核心的思路,使用 表B 的数据,来更新 表A 的记录


注意点


因为 表B 相当于是更新需要的数据源,我们可以使用临时表来查询组合得到需要的数据集;表A 是更新的主体,则必须要为数据库中现有的表。 如果 表A 也使用临时表,则 mysql 会因为无法定位到实际需要更新的位置而报错。


如下图示,左侧正确 的操作示例,右侧 为将临时表当成更新主体表的 错误 示例:


成品 sql

UPDATE     mdm_basics b,    (SELECT            c3.id c3id,            c1.mdm_code c1code,            c1.mdm_name c1name,            c2.mdm_code c2code,            c2.mdm_name c2name,            c3.mdm_code c3code,            c3.mdm_name c3name     FROM            mdm_classification c3            LEFT JOIN mdm_classification c2 ON c2.mdm_code = LEFT ( c3.mdm_code, 4 )            LEFT JOIN mdm_classification c1 ON c1.mdm_code = LEFT ( c3.mdm_code, 2 )     WHERE            c3.mdm_code = '2302001'     ) c SET     b.mdm_classification_id = c.c3id,    b.mdm_group = c.c3code,    b.mdm_product_code3 = c.c3code,    b.mdm_classification_name = c.c3name,    b.mdm_product_name3 = c.c3name,    b.mdm_product_code1 = c.c1code,    b.mdm_product_name1 = c.c1name,    b.mdm_product_code2 = c.c2code,    b.mdm_product_name2 = c.c2name,    b.update_date = now() WHERE    b.mdm_code IN (        '20031500'     )
复制代码

总结

mysql 的强大,实际上已经超乎我们的想象,而占据我们日常开发中绝大部分工作的 CURD,也不过是 mysql 中的冰山一角。不要让我们的惯性思维,限制了我们对 mysql 的能力的探索

发布于: 刚刚阅读数: 3
用户头像

CV 工程师 2022.07.13 加入

还未添加个人简介

评论

发布
暂无评论
【MySql 实战】以 sql 的方式多表联动更新数据_MySQL_安逸的咸鱼_InfoQ写作社区