查看: 302|回复: 0

跨表查询经常有,何为跨表更新?

[复制链接]
发表于 2020-2-3 09:59:31 | 显示全部楼层 |阅读模式
有点 SQL 基础的朋友肯定听过 「跨表查询」,那啥是跨表更新啊?
配景

项目新导入了一批人员数据,这些人的有的部门名称发生了变化,有的联系方式发生了变化,暂且称该表为
t_dept_members, 系统中有另外一张表 t_user_info 记载了人员信息。要求将 t_dept_members 中有变化的信息更新到 t_user 表中,这个需求就是「跨表更新」啦
憨B SQL 直接被秒杀

不带脑筋出门的就写出了下面的 SQL
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084650294-1228770059.png[/img]

看到身后 DBA 小段总在修仙,想着让他帮润色一下,于是发给了他,然后甩手回来就是这个样子:
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084650928-2091943995.png[/img]


看到这个 SQL 语句我都惊呆了,还能这样写,在无情的嘲笑下,一声 KO 我直接倒下。死也得死的明白,咱得查查这是咋回事啊
Mysql Update Join

我们常常使用 join 查询表中具有(在 INNER JOIN 情况下)或可能没有(在 LEFT JOIN 情况下)另一个表中匹配行的表中的行。
同样,在 MySQL 中, 我们也可以在 UPDATE 语句中使用 JOIN 子句执行跨表更新,语法就是这样:
  1. UPDATE T1, T2,[INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2. C1SET T1.C2 = T2.C2,    T2.C3 = exprWHERE condition
复制代码
我们还是详细的阐明一下上面的语法:

  • 首先,在 UPDATE 子句之后,指定主表(T1)和希望主表联接到的表(T2)。请留意,必须在UPDATE 子句之后至少指定一个表
  • 接下来,指定你要使用的联接范例,即 INNER JOIN 或 LEFT JOIN 以及联接谓词。 JOIN子句必须出如今 UPDATE 子句之后(这个各人都是知道的哈)
  • 然后,将新值分配给要更新的 T1或 T2 表中的列
  • 最后,在 WHERE 子句中指定一个条件以将行限制为要更新的行
如果你遵循 update 语法,你会发现有另外一种语法也可以完成跨表更新
  1. UPDATE T1, T2SET T1.c2 = T2.c2,      T2.c3 = exprWHERE T1.c1 = T2.c1 AND condition
复制代码
上面的语法实在隐式使用了 inner join 关键字,完全等同于下面的样子:
  1. UPDATE T1,T2INNER JOIN T2 ON T1.C1 = T2.C1SET T1.C2 = T2.C2,      T2.C3 = exprWHERE condition
复制代码
个人建议还是加上 inner join 关键字吧,这样可读性更好,尽享丝滑,你以为呢?
我摸鱼看到的,以为是灵魂翻译
谈太廉,秀你码 (Talk is cheap,show me the code)
Update Join 例子

年底了,又到了评绩效的时间了,就是那个叫 KPI 的东东(你们有吗),听说要根据 KPI 调工资了。有两张表
第一张表「employees-员工表」
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084651541-1211950984.png[/img]

建表语句如下:
  1. create table employees(    employee_id bigint auto_increment comment '员工ID,主键',    employee_name varchar(50) null comment '员工名称',    performance int(4) null comment '绩效分数 1,2,3,4,5',    salary float null comment '员工薪水',    constraint employees_pk        primary key (employee_id))comment '员工表';
复制代码
第二张表「merits-绩效字典表」
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084652120-2129418582.png[/img]

建表语句如下:
  1. create table merits(    performance int(4) null,    percentage float null)comment '绩效字典表';
复制代码
先生成一些模拟数据
  1. -- 绩效字典初始化数据INSERT INTO merits(performance, percentage)VALUES (1, 0),       (2, 0.01),       (3, 0.03),       (4, 0.05),       (5, 0.08);-- 员工表初始化数据INSERT INTO employees(employee_name, performance, salary)VALUES ('拱哥', 1, 1000),       ('小段总', 3, 20000),       ('大人', 4, 18000),       ('司令', 5, 28000),       ('老六', 2, 10000),       ('罗蒙', 3, 20000);
复制代码
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084652957-295446563.png[/img]

调薪规则:
原有薪资 + (原有薪资 * 当前绩效对应的调薪百分比)
按照调薪规则写 update 语句:
  1. UPDATE employees    INNER JOIN    merits ON employees.performance = merits.performanceset salary = salary + salary * percentage;
复制代码
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084653722-1074699827.png[/img]

拱哥绩效不好,没给涨工资......
三横一竖一咕嘎,四个小猪来吃zha,咕嘎咕嘎又来俩
邻近年底,公司又来了两位新同事, 但是公司年度绩效已经评完,所以新员工绩效为 NULL
  1. INSERT INTO employees(employee_name, performance, salary)VALUES ('馮大', NULL, 8000),       ('馮二', NULL, 5000);
复制代码
新员工工作干的不错,也要 1.5% 涨点工资的。如果我们还是用 UPDATE INNER JOIN,按照上面的更新语句是不可能完成的,由于条件等式不成立,这是我们就要用到 UPDATE LEFT JOIN 了
  1. UPDATE employees    LEFT JOIN    merits ON employees.performance = merits.performanceSET salary = salary + salary * 0.015WHERE merits.percentage IS NULL;
复制代码
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084654752-2039561929.png[/img]

到这里,新员工的涨薪工作也做完,拱哥由于知识点了解不透彻,灰溜溜的回家过年

  • 如果你也恰巧刚知道这个知识点,请点个「赞」
  • 如果你早都知道了这个知识点,还请留言送上「嘘声」
  • 如果你年终奖丰厚,希望你2020年更进一步
  • 如果你和我一样没有年终奖,别灰心,我们携手进步
流感严重,春运旅途多加小心
欢迎持续关注公众号:「日拱一兵」


  • 前沿 Java 技术干货分享
  • 高效工具汇总 | 复兴「工具」
  • 口试标题分析与解答
  • 技术资料领取 | 复兴「资料」
以读侦探小说思维轻松意见意义学习 Java 技术栈相关知识,本着将复杂标题简单化,抽象标题具体化和图形化原则逐步分解技术标题,技术持续更新,请持续关注......
[img]https://img2018.cnblogs.com/blog/1583165/202002/1583165-20200203084658221-441361367.png[/img]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?用户注册

x

相关技术服务需求,请联系管理员和客服QQ:2753533861或QQ:619920289
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

帖子推荐:
客服咨询

QQ:2753533861

服务时间 9:00-22:00

快速回复 返回顶部 返回列表