Pour la "requête ne mettant pas à jour correctement les lignes" :
Vous souhaitez mettre à jour la colonne b
au minimum de b
pour toutes les lignes ayant le même a
Vous avez proposé d'utiliser le JOIN
suivant pour faire ça :
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;
Contrairement à ce que vous pourriez penser, ce JOIN
n'effectuera pas de JOIN
1-1 . Il s'agit en fait d'un JOIN
plusieurs-à-plusieurs depuis comme je l'ai dit hier
vous n'utilisez pas de clé primaire (ni de clé unique non nulle) dans votre clause de jointure.
En fait, réécrire cette requête en tant que SELECT
vous aidera probablement à comprendre le problème :
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
Comme vous le verrez maintenant, la ligne (1, null)
correspondre à (1, 1)
, (1, 2)
et (1, null)
. Selon l'ordre (non déterministe) d'exécution de la requête, cela peut affecter l'une des trois valeurs possibles pour b
(je n'en suis pas sûr, mais peut-être même en en mettant à jour plusieurs fois). Dans une certaine mesure, vous avez eu de la chance de trouver le "mauvais" résultat lors du test !
J'espère que cela explique un peu plus pourquoi votre requête ne produit pas le résultat attendu. Depuis multi-table UPDATE
les instructions n'autorisent pas ORDER BY
ni GROUP BY
clauses, quant à moi, pour trouver le "bon" résultat, je ne vois pas beaucoup d'autres options que de trouver le minimum d'abord via une sous-requête...