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