Untuk "permintaan tidak memperbarui baris dengan benar":
Anda ingin memperbarui kolom b
ke minimum dari b
untuk semua baris yang memiliki a
. yang sama
Anda mengusulkan untuk menggunakan JOIN
berikut ini untuk melakukan itu:
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;
Bertentangan dengan apa yang mungkin Anda pikirkan, bahwa JOIN
tidak akan melakukan 1-1 JOIN
. Ini sebenarnya adalah JOIN
banyak-ke-banyak sejak seperti yang saya katakan kemarin
Anda tidak menggunakan kunci utama (atau kunci unik non-null) dalam klausa gabungan Anda.
Faktanya, menulis ulang kueri itu sebagai SELECT
mungkin akan membantu Anda memahami masalahnya:
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
Seperti yang akan Anda lihat sekarang, baris (1, null)
cocokkan (1, 1)
, (1, 2)
dan (1, null)
. Bergantung pada urutan eksekusi kueri (non-deterministik), ini mungkin menetapkan salah satu dari tiga kemungkinan nilai untuk b
(Saya tidak yakin tentang itu, tapi mungkin bahkan memperbaruinya beberapa waktu). Sampai batas tertentu, Anda beruntung menemukan hasil yang "salah" saat menguji!
Saya harap ini menjelaskan sedikit lebih banyak mengapa kueri Anda tidak menghasilkan hasil yang diharapkan. Sejak multi-tabel UPDATE
pernyataan tidak mengizinkan ORDER BY
atau GROUP BY
klausa, seperti saya sendiri, untuk menemukan hasil "baik", saya tidak melihat banyak opsi selain menemukan pertama minimum melalui sub-kueri...