Để mở rộng câu trả lời của MguerraTorres :
(Cập nhật với thông tin từ truy vấn phụ của bạn)
Trong truy vấn đầu tiên của bạn UPDATE cte
nói để cập nhật bảng từ CTE.
FROM cte as a
nói để chỉ bảng từ CTE như a
.
Vì vậy, chúng tôi đã đề cập đến CTE của chúng tôi ở hai nơi.
Điều bạn có thể không nhận ra là CTE được đánh giá lại cho mỗi lần nó xuất hiện trong truy vấn của bạn, giống như khi bạn thay thế tham chiếu bằng truy vấn con. Vì bạn đã tham chiếu CTE hai lần riêng biệt, bạn đã tạo hai kết quả riêng biệt để công cụ DB hoạt động.
Khi bạn nói sử dụng b.Value
ở đâu a.ID = b.ID
, chúng tôi có hai hàng - một hàng b.Value
là 100 và một ở đó là 200 - từ bảng b
và từ kết quả CTE thứ hai của chúng tôi.
Tuy nhiên, chúng tôi đang cập nhật tập kết quả CTE đầu tiên dựa trên hai hàng này. Do đó, nó cập nhật từng hàng trong tập kết quả đầu tiên từ hai hàng được trả về. Không có mối quan hệ giữa hai kết quả, mặc dù chúng đại diện cho cùng một dữ liệu cơ bản. Công cụ đang thực hiện CROSS JOIN
giữa kết quả tham gia của bạn và kết quả đầu tiên để thực hiện cập nhật.
UPDATE
Tuyên bố của bạn cập nhật cả hai hàng của bạn thành 200, sau đó thành 100 (vì công cụ quyết định cách nhanh nhất để áp dụng các hàng được nối chéo, chúng có thể không đi theo thứ tự mà chúng được nhập). Cả hai hàng được cập nhật về cùng một giá trị vì chúng được cập nhật từ cùng một hàng.
Truy vấn đầu tiên của bạn giống hệt về chức năng:
DECLARE @a TABLE (ID int, Value int);
DECLARE @b TABLE (ID int, Value int);
INSERT @a VALUES (1, 10), (2, 20);
INSERT @b VALUES (1, 100),(2, 200);
WITH cte AS
(
SELECT * FROM @a
)
UPDATE cte
SET Value = b.Value
FROM (SELECT * FROM @a) AS a
INNER JOIN @b AS b
ON b.ID = a.ID
SELECT * FROM @a
GO
Trong truy vấn thứ hai của bạn, động cơ DB biết rằng cả hai a
và @a
tham khảo một bảng bên ngoài truy vấn, và nó biết rằng a
và @a
ý nghĩa giống nhau, vì vậy nó gắn một cách chính xác các hàng từ @b
để @a
khi thực hiện cập nhật.
Trong các ý kiến, bạn hỏi:
Kết quả sẽ luôn là 100 cho cả hai? hoặc có thể là 200 cho cả hai đôi khi - Theo tôi thấy không có quy tắc rõ ràng ở đây?
Cho dù đó là 100 hay 200 có thể thay đổi.
Tôi sẽ nói rằng có khả năng, với các câu lệnh tương tự được hiển thị trong truy vấn đầu tiên của bạn, được thực hiện theo cùng một cách, bạn gần như chắc chắn sẽ nhận được kết quả tương tự.
Tuy nhiên, trong thế giới thực, với các bảng nhìn thấy hoạt động khác, bạn không thể thực sự về kết quả này hay kết quả khác, đặc biệt là theo thời gian. Nó sẽ phụ thuộc vào cách công cụ DB khớp với các bảng trong phép nối và sau đó xử lý các hàng trong việc áp dụng bản cập nhật.