Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Dùng UNION ALL để INSERT vào 2 bảng cùng lúc trong một câu lệnh MySQL

MySQL cho phép kết hợp INSERT ... SELECT với UNION ALL để chèn dữ liệu từ một nguồn vào nhiều bảng, hoặc chèn nhiều tập kết quả khác nhau vào cùng một bảng — tất cả trong một câu lệnh duy nhất.

Ví dụ minh họa

Tạo bảng đích (DemoTable1):

mysql> CREATE TABLE DemoTable1 (
    StudentName VARCHAR(20),
    StudentMarks INT
);

Tạo bảng nguồn (DemoTable2):

mysql> CREATE TABLE DemoTable2 (
    Name VARCHAR(20)
);

Chèn 1 hàng vào bảng nguồn:

mysql> INSERT INTO DemoTable2 VALUES ('Chris');

INSERT vào DemoTable1 từ DemoTable2 với 2 giá trị Marks khác nhau (UNION ALL)

mysql> INSERT INTO DemoTable1
    SELECT Name, 89 FROM DemoTable2
    UNION ALL
    SELECT Name, 98 FROM DemoTable2;

Kết quả: 2 hàng được chèn vào DemoTable1:

mysql> SELECT * FROM DemoTable1;
+-------------+--------------+
| StudentName | StudentMarks |
+-------------+--------------+
| Chris       |           89 |
| Chris       |           98 |
+-------------+--------------+

Giải thích

  • SELECT Name, 89 FROM DemoTable2: Tạo hàng (Chris, 89).
  • SELECT Name, 98 FROM DemoTable2: Tạo hàng (Chris, 98).
  • UNION ALL: Gộp 2 tập kết quả (giữ trùng lặp — ở đây không trùng).
  • INSERT INTO DemoTable1 ...: Chèn toàn bộ kết quả gộp vào bảng đích.

UNION ALL vs UNION

Toán tửXử lý trùng lặpHiệu năngKhi nào dùng
UNION ALLGiữ tất cả (không loại trùng)Nhanh hơn (không sort/unique)Biết chắc không trùng, hoặc muốn giữ trùng
UNIONLoại trùng (DISTINCT)Chậm hơn (cần sort/hash)Cần kết quả duy nhất

Mở rộng: INSERT vào 2 bảng khác nhau cùng lúc

MySQL không hỗ trợ INSERT INTO table1, table2 ... trong một câu lệnh. Giải pháp:

  1. Transaction: Bọc 2 INSERT riêng biệt trong START TRANSACTION ... COMMIT.
  2. Trigger: AFTER INSERT trên bảng 1 → INSERT vào bảng 2.
  3. Application layer: Gọi 2 INSERT từ code ứng dụng trong 1 transaction.
  4. Stored Procedure: Góc 2 INSERT trong 1 proc.

Ví dụ thực tế: Tạo bản ghi log + dữ liệu chính

INSERT INTO Orders (CustomerId, Amount, Status)
SELECT CustomerId, Amount, 'Pending' FROM TempOrders
UNION ALL
SELECT CustomerId, Amount, 'Pending' FROM TempOrders2;

-- Hoặc dùng CTE (MySQL 8.0+)
WITH Combined AS (
    SELECT CustomerId, Amount FROM TempOrders
    UNION ALL
    SELECT CustomerId, Amount FROM TempOrders2
)
INSERT INTO Orders (CustomerId, Amount, Status)
SELECT CustomerId, Amount, 'Pending' FROM Combined;