Đối với "truy vấn không cập nhật chính xác các hàng":
Bạn muốn cập nhật cột b
ở mức tối thiểu trong tổng số b
cho tất cả các hàng có cùng a
Bạn đã đề xuất sử dụng JOIN
sau để làm điều đó:
UPDATE test.tem t1
JOIN test.tem t2
ON t1.a = t2.a
SET t1.b = t2.b
WHERE t1.b > t2.b
OR t1.b IS NULL;
Trái ngược với những gì bạn có thể nghĩ, JOIN
sẽ không thực hiện 1-1 JOIN
. Trên thực tế, nó là một JOIN
nhiều-nhiều vì như tôi đã nói hôm qua
bạn không sử dụng khóa chính (hoặc khóa duy nhất không rỗng) trong mệnh đề tham gia của mình.
Trên thực tế, viết lại truy vấn đó dưới dạng SELECT
có thể sẽ giúp bạn hiểu vấn đề:
SELECT t1.a as t1a, t1.b as t1b, t2.a as t2a,t2.b as t2b FROM tem t1 JOIN tem t2
ON t1.a = t2.a
WHERE t1.b > t2.b
OR t1.b IS NULL;
+------+---------+------+--------+
| T1A | T1B | T2A | T2B |
+------+---------+------+--------+
| 1 | (null) | 1 | 2 |
| 1 | 2 | 1 | 1 |
| 1 | (null) | 1 | 1 |
| 1 | (null) | 1 | (null) |
+------+---------+------+--------+
http://sqlfiddle.com/#!2/856a7/8
Như bạn sẽ thấy bây giờ, hàng (1, null)
khớp với (1, 1)
, (1, 2)
và (1, null)
. Tùy thuộc vào thứ tự thực thi (không xác định) của truy vấn, điều này có thể chỉ định bất kỳ giá trị nào trong số ba giá trị có thể có cho b
(Tôi không chắc về điều đó, nhưng có thể thậm chí cập nhật nó một số lần). Ở một số khía cạnh, bạn đã may mắn tìm thấy kết quả "sai" trong khi kiểm tra!
Tôi hy vọng điều này giải thích thêm một chút tại sao truy vấn của bạn không tạo ra kết quả như mong đợi. Vì nhiều bảng UPDATE
câu lệnh không cho phép ORDER BY
cũng không phải GROUP BY
đối với bản thân tôi, để tìm ra kết quả "tốt", tôi không thấy có nhiều lựa chọn khác ngoài việc tìm giá trị tối thiểu đầu tiên thông qua một truy vấn phụ ...