MERGE trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng câu lệnh MERGE trong SQL Server để cập nhật dữ liệu trong bảng dựa trên các giá trị được khớp từ một bảng khác.

Giới thiệu câu lệnh MERGE trong SQL Server

Giả sử, bạn có hai bảng được gọi là bảng nguồn (source table) và bảng mục tiêu (target table), và bạn cần cập nhật bảng mục tiêu dựa trên các giá trị được khớp từ bảng nguồn. Có ba trường hợp:

  1. Bảng nguồn có một số hàng không tồn tại trong bảng đích. Trong trường hợp này, bạn cần INSERT các hàng trong bảng nguồn vào bảng đích.
  2. Bảng đích có một số hàng không tồn tại trong bảng nguồn. Trong trường hợp này, bạn cần DELETE các hàng khỏi bảng đích.
  3. Bảng nguồn có một số hàng có cùng khóa với các hàng trong bảng đích. Tuy nhiên, các hàng này có các giá trị khác nhau trong các cột không phải khóa. Trong trường hợp này, bạn cần UPDATE các hàng trong bảng đích với các giá trị đến từ bảng nguồn.

Hình ảnh sau minh họa bảng nguồn và bảng đích với các hành động tương ứng: chèn, cập nhật và xóa:

Câu lệnh MERGE trong SQL Server

Nếu bạn sử dụng câu lệnh INSERT, UPDATEDELETE độc lập, bạn phải xây dựng ba câu lệnh riêng biệt để cập nhật dữ liệu vào bảng đích với các hàng kết hợp từ bảng nguồn.

Tuy nhiên, SQL Server cung cấp câu lệnh MERGE cho phép bạn thực hiện ba hành động cùng một lúc. Sau đây là cú pháp của câu lệnh MERGE:

MERGE target_table USING source_table
ON merge_condition
WHEN MATCHED
    THEN update_statement
WHEN NOT MATCHED
    THEN insert_statement
WHEN NOT MATCHED BY SOURCE
    THEN DELETE;

Đầu tiên, bạn chỉ định bảng đích và bảng nguồn trong mệnh đề MERGE.

Thứ hai, biểu thức merge_condition xác định cách các hàng từ bảng nguồn được khớp với các hàng từ bảng đích. Nó tương tự như điều kiện join trong mệnh đề JOIN. Thông thường, bạn sử dụng các cột khóa hoặc khóa chính (primary key) hoặc khóa duy nhất (unique key) để đối sánh.

Thứ ba, biểu thức merge_condition trả về kết quả trong ba trạng thái: MATCHED, NOT MATCHED, và NOT MATCHED BY SOURCE.

  • MATCHED: đây là những hàng phù hợp với điều kiện hợp nhất. Trong biểu đồ, chúng được hiển thị dưới dạng màu xanh lam. Đối với các hàng phù hợp, bạn cần cập nhật các cột hàng trong bảng đích với các giá trị từ bảng nguồn.
  • NOT MATCHED: đây là những hàng từ bảng nguồn không có bất kỳ hàng nào phù hợp trong bảng đích. Trong sơ đồ, chúng được hiển thị dưới dạng màu cam. Trong trường hợp này, bạn cần thêm các hàng từ bảng nguồn vào bảng đích. Lưu ý rằng NOT MATCHED còn được gọi là NOT MATCHED BY TARGET.
  • NOT MATCHED BY SOURCE: đây là những hàng trong bảng đích không khớp với bất kỳ hàng nào trong bảng nguồn. Chúng được hiển thị dưới dạng màu xanh lá cây trong sơ đồ. Nếu bạn muốn đồng bộ hóa bảng mục tiêu với dữ liệu từ bảng nguồn, thì bạn sẽ cần sử dụng điều kiện đối sánh này để xóa các hàng khỏi bảng mục tiêu.

Ví dụ về câu lệnh MERGE trong SQL Server

Giả sử chúng ta có hai bảng sales.categorysales.category_staging lưu trữ doanh số bán hàng theo danh mục sản phẩm.

CREATE TABLE sales.category (
    category_id INT PRIMARY KEY,
    category_name VARCHAR(255) NOT NULL,
    amount DECIMAL(10 , 2 )
);

INSERT INTO sales.category(category_id, category_name, amount)
VALUES(1,'Children Bicycles',15000),
    (2,'Comfort Bicycles',25000),
    (3,'Cruisers Bicycles',13000),
    (4,'Cyclocross Bicycles',10000);


CREATE TABLE sales.category_staging (
    category_id INT PRIMARY KEY,
    category_name VARCHAR(255) NOT NULL,
    amount DECIMAL(10 , 2 )
);


INSERT INTO sales.category_staging(category_id, category_name, amount)
VALUES(1,'Children Bicycles',15000),
    (3,'Cruisers Bicycles',13000),
    (4,'Cyclocross Bicycles',20000),
    (5,'Electric Bikes',10000),
    (6,'Mountain Bikes',10000);

Để cập nhật dữ liệu vào bảng sales.category (bảng đích) với các giá trị từ  bảng sales.category_staging (bảng nguồn), bạn sử dụng câu lệnh MERGE sau :

MERGE sales.category t 
    USING sales.category_staging s
ON (s.category_id = t.category_id)
WHEN MATCHED
    THEN UPDATE SET 
        t.category_name = s.category_name,
        t.amount = s.amount
WHEN NOT MATCHED BY TARGET 
    THEN INSERT (category_id, category_name, amount)
         VALUES (s.category_id, s.category_name, s.amount)
WHEN NOT MATCHED BY SOURCE 
    THEN DELETE;
Ví dụ về câu lệnh MERGE trong SQL Server

Trong ví dụ này, chúng tôi đã sử dụng giá trị trong cột category_id trong cả hai bảng làm điều kiện hợp nhất.

  • Đầu tiên, các hàng có id 1, 3, 4 từ bảng sales.category_staging khớp với các hàng từ bảng đích, do đó, câu lệnh MERGE cập nhật các giá trị trong các cột category_name và amount trong bảng sales.category.
  • Thứ hai, các hàng có id 5 và 6 từ bảng sales.category_staging không tồn tại trong bảng sales.category, vì vậy câu lệnh MERGE chèn các hàng này vào bảng đích.
  • Thứ ba, hàng có id 2 từ bảng sales.category không tồn tại trong bảng sales.sales_staging, do đó, câu lệnh MERGE sẽ xóa hàng này.

Kết quả của việc hợp nhất, dữ liệu trong bảng sales.category được đồng bộ hóa hoàn toàn với dữ liệu trong bảng sales.category_staging.

Trong hướng dẫn này, bạn đã học cách sử dụng câu lệnh MERGE trong SQL Server để thực hiện các thay đổi trong bảng dựa trên các giá trị khớp từ một bảng khác.

SQL Server
Bài Viết Liên Quan:
Hướng dẫn đầy đủ về Expression trong SQL Server
Trung Nguyen 18/03/2021
Hướng dẫn đầy đủ về Expression trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng biểu thức CASE, COALESCE và NULLIF trong SQL Server.

NULLIF trong SQL Server
Trung Nguyen 18/03/2021
NULLIF trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng biểu thức NULLIF trong SQL Server để trả về NULL nếu đối số đầu tiên bằng đối số thứ hai.

COALESCE trong SQL Server
Trung Nguyen 18/03/2021
COALESCE trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng biểu thức COALESCE trong SQL Server để xử lý giá trị NULL trong các truy vấn.

CASE trong SQL Server
Trung Nguyen 18/03/2021
CASE trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng biểu thức CASE trong SQL Server để thêm logic if-else vào các truy vấn SQL.