Para la "consulta que no actualiza correctamente las filas":
Quiere actualizar la columna b
al mínimo de b
para todas las filas que tengan el mismo a
Propusiste usar el siguiente JOIN
para hacer eso:
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;
Al contrario de lo que puedas pensar, eso JOIN
no realizará un 1-1 JOIN
. De hecho, es un JOIN
de muchos a muchos desde como dije ayer
no usa la clave principal (ni la clave única no nula) en su cláusula de unión.
De hecho, reescribiendo esa consulta como SELECT
probablemente te ayudará a entender el 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
Como verá ahora, la fila (1, null)
coincide con (1, 1)
, (1, 2)
y (1, null)
. Dependiendo del orden (no determinista) de ejecución de la consulta, esto podría asignar cualquiera de los tres valores posibles para b
(No estoy seguro de eso, pero tal vez incluso actualizándolo varios veces). ¡Hasta cierto punto, ha tenido suerte de encontrar el resultado "incorrecto" durante la prueba!
Espero que esto explique un poco más por qué su consulta no produce el resultado esperado. Dado que las tablas múltiples UPDATE
las declaraciones no permiten ORDER BY
ni GROUP BY
cláusulas, por mi parte, para encontrar el resultado "bueno", no veo muchas otras opciones que encontrar el mínimo primero a través de una subconsulta...