Ba câu lệnh giải ba bài toán khác nhau.
UPDATE ... FROM — chỉ cập nhật dòng đã có, lấy giá trị từ bảng nguồn (cú pháp riêng của PostgreSQL):
UPDATE products p
SET price = s.new_price, updated_at = now()
FROM staging_prices s
WHERE p.sku = s.sku AND p.price IS DISTINCT FROM s.new_price;Bẫy: nếu bảng nguồn có nhiều dòng khớp cùng một dòng đích, PostgreSQL chọn một dòng không xác định và không báo lỗi — phải khử trùng lặp ở nguồn trước (DISTINCT ON hoặc GROUP BY).
MERGE (chuẩn SQL, PostgreSQL 15+) — một lệnh xử lý cả ba nhánh khớp/không khớp:
MERGE INTO products p
USING staging_prices s ON p.sku = s.sku
WHEN MATCHED AND p.price <> s.new_price THEN UPDATE SET price = s.new_price
WHEN NOT MATCHED THEN INSERT (sku, price) VALUES (s.sku, s.new_price)
WHEN MATCHED AND s.discontinued THEN DELETE;INSERT ... ON CONFLICT — chỉ xử lý xung đột trên ràng buộc unique/PK, nhưng đổi lại là thao tác an toàn khi chạy song song: PostgreSQL khoá dòng xung đột nên hai session cùng chèn sẽ không sinh dòng trùng.
Cách chọn:
- Chỉ update theo bảng nguồn → UPDATE ... FROM, đơn giản nhất.
- Đồng bộ ETL cần cả insert/update/delete trong một lượt → MERGE.
- Upsert từ API dưới tải đồng thời → INSERT ... ON CONFLICT. MERGE không tự chống race condition: hai transaction cùng chạy có thể cùng rơi vào nhánh NOT MATCHED và một bên nhận lỗi unique violation.