Per la "query non aggiorna correttamente le righe":
Vuoi aggiornare la colonna b
al minimo di b
per tutte le righe che hanno lo stesso a
Hai proposto di utilizzare il seguente JOIN
per farlo:
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;
Contrariamente a quello che potresti pensare, quel JOIN
non eseguirà un JOIN
1-1 . In effetti è un JOIN
molti-a-molti poiché come ho detto ieri
non usi la chiave primaria (né una chiave univoca non nulla) nella tua clausola di join.
In effetti, riscrivendo quella query come SELECT
probabilmente ti aiuterà a capire il problema:
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
Come vedrai ora, la riga (1, null)
corrisponde a (1, 1)
, (1, 2)
e (1, null)
. A seconda dell'ordine (non deterministico) di esecuzione della query, questo potrebbe assegnare uno qualsiasi dei tre possibili valori per b
(non ne sono sicuro, ma forse anche aggiornandolo diversi volte). In una certa misura, sei stato fortunato a trovare il risultato "sbagliato" durante il test!
Spero che questo spieghi un po' di più perché la tua query non produce il risultato atteso. Poiché UPDATE
multi-tabella
le istruzioni non consentono ORDER BY
né GROUP BY
clausole, come per me, per trovare il risultato "buono", non vedo molte altre opzioni che trovare il minimo prima tramite una sottoquery...