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

有点 SQL 基础的朋友确定听过 「跨表查询」,那啥是跨表更新啊?面试

背景

项目新导入了一批人员数据,这些人的有的部门名称发生了变化,有的联系方式发生了变化,暂且称该表为sql

t_dept_members, 系统中有另一张表 t_user_info 记录了人员信息。要求将 t_dept_members 中有变化的信息更新到 t_user 表中,这个需求就是「跨表更新」啦工具

憨B SQL 直接被秒杀

不带脑子出门的就写出了下面的 SQL学习

看到身后 DBA 小段总在修仙,想着让他帮润色一下😜,因而发给了他,而后甩手回来就是这个样子:ui

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

Mysql Update Join

咱们常常使用 join 查询表中具备(在 INNER JOIN 状况下)或可能没有(在 LEFT JOIN 状况下)另外一个表中匹配行的表中的行。翻译

一样,在 MySQL 中, 咱们也能够在 UPDATE 语句中使用 JOIN 子句执行跨表更新,语法就是这样:3d

UPDATE T1, T2,
[INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2. C1
SET T1.C2 = T2.C2,
    T2.C3 = expr
WHERE condition
复制代码

咱们仍是详细的说明一下上面的语法:code

  • 首先,在 UPDATE 子句以后,指定主表(T1)和但愿主表联接到的表(T2)。请注意,必须在UPDATE 子句以后至少指定一个表
  • 接下来,指定你要使用的联接类型,即 INNER JOIN 或 LEFT JOIN 以及联接谓词。 JOIN子句必须出如今 UPDATE 子句以后(这个你们都是知道的哈)
  • 而后,将新值分配给要更新的 T1或 T2 表中的列
  • 最后,在 WHERE 子句中指定一个条件以将行限制为要更新的行

若是你遵循 update 语法,你会发现有另一种语法也能够完成跨表更新orm

UPDATE T1, T2
SET T1.c2 = T2.c2,
      T2.c3 = expr
WHERE T1.c1 = T2.c1 AND condition
复制代码

上面的语法其实隐式使用了 inner join 关键字,彻底等同于下面的样子:

UPDATE T1,T2
INNER JOIN T2 ON T1.C1 = T2.C1
SET T1.C2 = T2.C2,
      T2.C3 = expr
WHERE condition
复制代码

我的建议仍是加上 inner join 关键字吧,这样可读性更好,尽享丝滑,你以为呢?

我摸鱼看到的,以为是灵魂翻译

谈太廉,秀你码 (Talk is cheap,show me the code)

Update Join 例子

年末了,又到了评绩效的时候了,就是那个叫 KPI 的东东(大家有吗),据说要根据 KPI 调工资了。有两张表

第一张表「employees-员工表」

建表语句以下:

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-绩效字典表」

建表语句以下:

create table merits
(
	performance int(4) null,
	percentage float null
)
comment '绩效字典表';
复制代码

先生成一些模拟数据

-- 绩效字典初始化数据
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);
复制代码

调薪规则:

原有薪资 + (原有薪资 * 当前绩效对应的调薪百分比)

按照调薪规则写 update 语句:

UPDATE employees
    INNER JOIN
    merits ON employees.performance = merits.performance
SET salary = salary + salary * percentage;
复制代码

拱哥绩效很差,没给涨工资......

三横一竖一咕嘎,四个小猪🐷来吃zha,咕嘎咕嘎又来俩

临近年末,公司又来了两位新同事, 可是公司年度绩效已经评完,因此新员工绩效为 NULL

INSERT INTO employees(employee_name, performance, salary)
VALUES ('馮大', NULL, 8000),
       ('馮二', NULL, 5000);
复制代码

新员工工做干的不错,也要 1.5% 涨点工资的。若是咱们仍是用 UPDATE INNER JOIN,按照上面的更新语句是不可能完成的,由于条件等式不成立,这是咱们就要用到 UPDATE LEFT JOIN

UPDATE employees
    LEFT JOIN
    merits ON employees.performance = merits.performance
SET salary = salary + salary * 0.015
WHERE merits.percentage IS NULL;
复制代码

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


  • 若是你也恰巧刚知道这个知识点,请点个「赞」

  • 若是你早都知道了这个知识点,还请留言送上「嘘声」

  • 若是你年终奖丰厚,但愿你2020年更进一步

  • 若是你和我同样没有年终奖,别灰心,咱们携手进步

流感严重😷,春运旅途多加当心

我的博客:https://dayarch.top

欢迎持续关注公众号:「日拱一兵」

  • 前沿 Java 技术干货分享
  • 高效工具汇总 | 回复「工具」
  • 面试问题分析与解答
  • 技术资料领取 | 回复「资料」

以读侦探小说思惟轻松趣味学习 Java 技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,请持续关注......


相关文章
相关标签/搜索