Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Etapas internas de atualização de junção do MYSQL


Para a "consulta não atualizando corretamente as linhas":

Você deseja atualizar a coluna b para o mínimo de b para todas as linhas com o mesmo a

Você propôs usar o seguinte JOIN fazer isso:
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;

Ao contrário do que você possa pensar, esse JOIN não executará um JOIN 1-1 . Na verdade, é um JOIN de muitos para muitos desde como eu disse ontem você não usa chave primária (nem chave exclusiva não nula) em sua cláusula de junção.

Na verdade, reescrever essa consulta como SELECT provavelmente irá ajudá-lo a entender o 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 você verá agora, a linha (1, null) corresponder (1, 1) , (1, 2) e (1, null) . Dependendo da ordem (não determinística) de execução da consulta, isso pode atribuir qualquer um dos três valores possíveis para b (não tenho certeza sobre isso, mas talvez mesmo atualizando vários vezes). Até certo ponto, você teve sorte de encontrar o resultado "errado" durante o teste!

Espero que isso explique um pouco mais por que sua consulta não produz o resultado esperado. Desde multi-tabela UPDATE instruções não permitem ORDER BY nem GROUP BY cláusulas, quanto a mim, para encontrar o resultado "bom", não vejo muitas outras opções além de encontrar o mínimo primeiro através de uma sub-consulta...