Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL join aggiornamento passaggi interni

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 BYGROUP BY clausole, come per me, per trovare il risultato "buono", non vedo molte altre opzioni che trovare il minimo prima tramite una sottoquery...