[MySql actual combat] Multi-table linkage update data in sql way

In layman's terms, an update operation needs to use the data in the associated table to update the target table.

According to the habit of use, whether it is in the backend of Java navicator Java, it needs to be divided into at least 2 pieces of sql for operation.

Because this kind of requirement is to perform operations in the DB occasionally, it is impossible to run the background every time; it is also impossible to manually query the target data every time, and then modify the updatestatement to execute

Table Structure

A classification table mdm_classification, in which the data mapping of primary, secondary and tertiary classification will be combined using the field parentnesting doll. The length of the code corresponding to the classification is 2 digits, 4 digits, and 7 digits respectively, and the naming style is: aa, aabb, aabbccc, That is, the first and second grades can be obtained through the specific three-level codeinterception .code

A material table mdm_basicswill have its own unique code, and by mdm_classification_idbinding its own three-level classification and having redundant fields mdm_product_code1, mdm_product_code2, mdm_product_code3to bind its corresponding first, second, and third-level classification corresponding codeandname

Scenes

There is code=1a material with a bound 3-level classification codeof 1301001, and it needs to be switched to 2302001. At this time, the primary and secondary classification data to which this material belongs also needs to be maintained synchronously.

conventional solution

A background is required. 2302001For the first and second classifications obtained by interception code, go to DB to query to obtain the codecorresponding classification record data, and after splicing update sql, go to DB for execution, and the data will be updated and stored in the database.

sql solution

Self-connection to complete data for classification table

Through the left join method, for the records of the third-level classification we need to query, complete the corresponding first- and second-level classification recordscode、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 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' 
复制代码

联表查询后的效果如下

c3id c1code c1name c2code c2name c3code c3name
***750b02 23 标准件 2302 铆钉 2302001 标准件半圆头铆钉

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

联表更新

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

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

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

注意点

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

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

image.png

成品 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 的能力的探索

题外话:已解锁的能力

这些都是,在 DB 中,通过 sql 的方式解决问题:

高度聚合的数据项拆分为多行多列,将按特定分隔符特定格式组合而成的数据,用 sql 拆分

复杂触发器案例分享,通过触发器,实现日志记录,且值记录变更的字段的前后值

多行数据转化为同一行多列显示,通过 sql,将 DB 中数据显示的维度,由行,转化为列

批量更新,使用 mysql 的特性,1条 sql 解决千人千面式的数据更新(每条数据变更的点都不同)


原创文章,未经允许,禁止转载

create by:安逸的咸鱼

Guess you like

Origin juejin.im/post/7079949500197896222