Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

UPDATE ข้อมูลในตารางจากอีกตารางใน MySQL ด้วย JOIN

ไวยากรณ์ UPDATE ... JOIN

UPDATE target_table t1
JOIN source_table t2 ON t1.join_col = t2.join_col
SET t1.target_col = t2.source_col
[WHERE condition];

ตัวอย่าง: demo54 (มี lastName) → demo55 (lastName เป็น NULL)

CREATE TABLE demo54 (
    firstName VARCHAR(20),
    lastName VARCHAR(20)
);

CREATE TABLE demo55 (
    firstName VARCHAR(20),
    lastName VARCHAR(20)
);

INSERT INTO demo54 VALUES ('John','Smith'), ('John','Smith'), ('David','Smith');
INSERT INTO demo55 (firstName) VALUES ('John'), ('David'), ('Bob');

ข้อมูลก่อน UPDATE

demo54:

+-----------+----------+
| firstName | lastName |
+-----------+----------+
| John      | Smith    |
| John      | Smith    |
| David     | Smith    |
+-----------+----------+

demo55:

+-----------+----------+
| firstName | lastName |
+-----------+----------+
| John      | NULL     |
| David     | NULL     |
| Bob       | NULL     |
+-----------+----------+

คำสั่ง UPDATE JOIN

UPDATE demo55 t1
JOIN demo54 t2 ON t1.firstName = t2.firstName
SET t1.lastName = t2.lastName;

ผลลัพธ์หลัง UPDATE

+-----------+----------+
| firstName | lastName |
+-----------+----------+
| John      | Smith    |
| David     | Smith    |
| Bob       | NULL     |
+-----------+----------+

Bob ไม่เปลี่ยน เพราะไม่มีใน demo54

รายละเอียดสำคัญ

  • t1, t2 = Table Aliases (จำเป็นเมื่อคอลัมน์ซ้ำชื่อ)
  • JOIN = INNER JOIN → อัปเดตเฉพาะที่ Match ทั้งคู่
  • ใช้ LEFT JOIN หากต้องการอัปเดตทุกแถวของ t1 (SET NULL ถ้าไม่ Match)

รูปแบบ LEFT JOIN UPDATE

UPDATE demo55 t1
LEFT JOIN demo54 t2 ON t1.firstName = t2.firstName
SET t1.lastName = COALESCE(t2.lastName, t1.lastName);

คงค่าเดิมถ้าไม่ Match (Bob คง NULL)

หลายคอลัมน์ / หลายตาราง

UPDATE target t
JOIN source1 s1 ON t.id = s1.id
JOIN source2 s2 ON t.id = s2.id
SET t.col1 = s1.val, t.col2 = s2.val;

ข้อควรระวัง

  • Duplicate Matches: หาก source_table มีหลายแถวต่อ 1 Join Key → ผลลัพธ์ไม่แน่นอน (MySQL เลือกแถวไหนก็ได้)
  • แก้: ใช้ Subquery + Aggregate หรือ LIMIT 1 ใน Derived Table
  • Transaction: ใส่ใน Transaction หาก Critical
  • Replication: Row-based Replication จะ replicate แถวที่เปลี่ยนจริง

ตัวอย่างแก้ Duplicate Match

UPDATE demo55 t1
JOIN (
    SELECT firstName, MAX(lastName) AS lastName  -- หรือ ANY_VALUE()
    FROM demo54 GROUP BY firstName
) t2 ON t1.firstName = t2.firstName
SET t1.lastName = t2.lastName;

MySQL 8.0: CTE UPDATE

WITH latest AS (
    SELECT firstName, lastName FROM demo54
    WHERE id IN (SELECT MAX(id) FROM demo54 GROUP BY firstName)
)
UPDATE demo55 t1
JOIN latest t2 ON t1.firstName = t2.firstName
SET t1.lastName = t2.lastName;