sql >> Base de Datos >  >> RDS >> Mysql

Pasos internos de actualización de unión de MYSQL

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...