UPDATE INNER JOIN和UPDATE LEFT JOIN跨表更新

发布时间 2023-07-05 14:35:46作者: 周文豪

UPDATE JOIN 是用于执行跨表更新的 MySQL 语句,这意味着我们可以使用带有 JOIN 子句条件的另一个表来更新一个表。此查询根据PRIMARY KeyFOREIGN Key以及指定的连接条件更新和更改多个表连接的数据。我们可以使用UPDATE 查询一次更新单个或多个列。

一、MySQL Update Join 语法

以下是 UPDATE JOIN 语句将记录修改到 MySQL 表中的基本语法:

UPDATE Tab1, Tab2, [INNER JOIN | LEFT JOIN] Tab1 ON Tab1.C1 = Tab2.C1  
SET Tab1.C2 = Tab2.C2, Tab2.C3 = expression  
WHERE Condition;

在上面的 MySQL UPDATE JOIN 语法中:

首先,我们在 UPDATE 子句之后指定了两个表:主表 (Tab1) 和另一个表 (tab2)。

(1)、在 UPDATE 子句之后,需要指定至少一个表。

(2)、我们指定了JOIN 子句的类型,即INNER JOINLEFT JOIN,它们出现在 UPDATE 子句之后,然后是在 ON 关键字之后指定的连接谓词。

(3)、我们必须将新值分配给 Tab1 和/或 Tab2 中的列,以便修改到表中。

(4)、WHERE 子句条件用于限制要更新的行。

二、UPDATE JOIN 在 MySQL 中是如何工作的?

MySQL中的 UPDATE JOIN 工作过程与上述语法中描述的相同。但有时,我们会发现这个查询单独执行了跨表更新,而不涉及任何连接。以下语法是使用另一个表更新一个表的另一种方法:

两表:

UPDATE Tab1, Tab2,   
SET Tab1.C2 = Tab2.C2, Tab2.C3 = expression   
WHERE Tab1.C1 = Tab2.C1 AND condition;  

注意:condition条件用于限制要更新的行。

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

UPDATE T1,T2
INNERJOIN T2 ON T1.C1 = T2.C1
SET T1.C2 = T2.C2,
      T2.C3 = expr
WHERE condition

个人建议还是加上 inner join 关键字吧,这样可读性更好。

三表:

<update id="update1">
        UPDATE Tab1 a,
            Tab2 b,
            Tab3 c
        SET a.pro_name = c.product_name
            WHERE
             a.code_prefix = b.code_prefix
             AND b.prod_id = c.id
             AND a.subtypeno IS NULL
    </update>

让我们举一些例子来了解 UPDATE JOIN 语句在 MySQL 表中是如何工作的。

三、MySQL Update Join 示例

首先,我们将创建两个名为Performance和Employee的表,这两个表通过外键关联。这里,“Performance”是父表,“Employees”是子 表。以下脚本将创建两个表及其记录。

Performance表:

CREATE TABLE Performance (  
    performance INT(11) NOT NULL,  
    percentage FLOAT NOT NULL,  
    PRIMARY KEY (performance)  
); 

接下来,使用 INSERT 语句填充表中的记录。

INSERT INTO Performance (performance, percentage)  
VALUES(101,0),  
      (102,0.01),  
      (103,0.03),  
      (104,0.05),  
      (105,0.08);  

然后,执行 SELECT 查询以验证数据,如下图所示:

mysql> select * from performance;
+-------------+------------+
| performance | percentage |
+-------------+------------+
|         101 |          0 |
|         102 |       0.01 |
|         103 |       0.03 |
|         104 |       0.05 |
|         105 |       0.08 |
+-------------+------------+
5 rows in set (0.00 sec)

Employee表:

CREATE TABLE Employees (  
    id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    performance INT(11) DEFAULT NULL,  
    salary FLOAT DEFAULT NULL,  
    CONSTRAINT fk_performance FOREIGN KEY (performance) REFERENCES Performance (performance)  
);  

接下来,使用 INSERT 语句填充表中的记录。

INSERT INTO Employees (name, performance, salary)        
VALUES('Mary', 101, 55000),  
      ('John', 103, 65000),  
      ('Suzi', 104, 85000),  
      ('Gracia', 105, 110000),  
      ('Nancy Johnson', 103, 95000),  
      ('Joseph', 102, 45000),  
      ('Donald', 103, 50000); 

然后,执行 SELECT 查询以验证数据,如下图所示:

mysql> select * from employees;
+----+---------------+-------------+--------+
| id | name          | performance | salary |
+----+---------------+-------------+--------+
|  1 | Mary          |         101 |  55000 |
|  2 | John          |         103 |  65000 |
|  3 | Suzi          |         104 |  85000 |
|  4 | Gracia        |         105 | 110000 |
|  5 | Nancy Johnson |         103 |  95000 |
|  6 | Joseph        |         102 |  45000 |
|  7 | Donald        |         103 |  50000 |
+----+---------------+-------------+--------+
7 rows in set (0.00 sec)

假设我们想根据员工的表现更新员工的薪水。我们可以使用 UPDATE INNER JOIN 语句更新员工表中员工的薪水,因为绩效百分比存储在绩效表中。

在上面的表格中,我们必须使用绩效字段来连接员工和绩效表。请参阅以下查询:

UPDATE Employees e  
INNER JOIN Performance p   
ON e.performance = p.performance  
SET salary = salary + salary * percentage; 

执行上述语句后,我们会得到下面的输出,其中我们可以看到员工的工资列更新成功。

mysql> select * from employees;
+----+---------------+-------------+--------+
| id | name          | performance | salary |
+----+---------------+-------------+--------+
|  1 | Mary          |         101 |  55000 |
|  2 | John          |         103 |  66950 |
|  3 | Suzi          |         104 |  89250 |
|  4 | Gracia        |         105 | 118800 |
|  5 | Nancy Johnson |         103 |  97850 |
|  6 | Joseph        |         102 |  45450 |
|  7 | Donald        |         103 |  51500 |
+----+---------------+-------------+--------+
7 rows in set (0.00 sec)

让我们了解这个查询在 MySQL 中是如何工作的。在查询中,我们只在 UPDATE 子句之后指定了Employees 表。这是因为我们只想更改Employees 表中的记录,而不是两个表中的记录

该查询根据“Performance”表的绩效列检查“员工”表中每一行的绩效列值。如果它会得到匹配的绩效列,那么它将获取绩效表中的百分比并更新员工表的薪水列。该查询更新了Employees 表中的所有记录,因为我们没有在UPDATE JOIN 查询中指定WHERE 子句

五、MySQL INNER JOIN 和 Update Join 使用示例

为了理解 UPDATE JOIN 和 LEFT JOIN,我们首先需要在Employees 表中插入两个新行:

INSERT INTO Employees (name, performance, salary)  
VALUES('William', NULL, 73000),  
      ('Rayan', NULL, 92000); 

由于这些员工是新员工,因此他们的绩效记录不可用。请参阅以下输出:

mysql> select * from employees;
+----+---------------+-------------+--------+
| id | name          | performance | salary |
+----+---------------+-------------+--------+
|  1 | Mary          |         101 |  55000 |
|  2 | John          |         103 |  66950 |
|  3 | Suzi          |         104 |  89250 |
|  4 | Gracia        |         105 | 118800 |
|  5 | Nancy Johnson |         103 |  97850 |
|  6 | Joseph        |         102 |  45450 |
|  7 | Donald        |         103 |  51500 |
|  8 | William       |        NULL |  73000 |
|  9 | Rayan         |        NULL |  92000 |
+----+---------------+-------------+--------+
9 rows in set (0.00 sec)

如果我们想更新新雇员的薪水,我们不能使用 UPDATE INNER JOIN 查询。这是因为他们的性能数据在性能表中不可用。因此,我们将使用 UPDATE LEFT JOIN 语句来满足这一需求。

MySQL 中的 UPDATE LEFT JOIN 语句用于在另一个表的对应行中没有找到记录时更新表中的一行。

例如,如果我们想将新聘员工的工资提高 2.5%,我们可以借助以下语句来做到这一点:

UPDATE Employees e  
LEFT JOIN Performance p   
ON e.performance = p.performance   
SET salary = salary + salary * 0.025  
WHERE p.percentage IS NULL;  

执行上述查询后,我们将得到如下图的输出,其中我们可以看到新入职员工的工资已成功更新。

mysql> select * from employees;
+----+---------------+-------------+--------+
| id | name          | performance | salary |
+----+---------------+-------------+--------+
|  1 | Mary          |         101 |  55000 |
|  2 | John          |         103 |  66950 |
|  3 | Suzi          |         104 |  89250 |
|  4 | Gracia        |         105 | 118800 |
|  5 | Nancy Johnson |         103 |  97850 |
|  6 | Joseph        |         102 |  45450 |
|  7 | Donald        |         103 |  51500 |
|  8 | William       |        NULL |  74825 |
|  9 | Rayan         |        NULL |  94300 |
+----+---------------+-------------+--------+
9 rows in set (0.00 sec)

在本文中,我们学习了 MySQL Update Join 语句,该语句允许我们使用 JOIN 子句条件将另一个表中的新数据更改为一个表中的现有数据。当我们需要修改 WHERE 子句中指定的某些列以及使用 INNER JOIN 或 LEFT JOIN 子句时,此查询非常有用。