For "forespørgslen opdaterer ikke rækkerne korrekt":
Du vil opdatere kolonne b
til minimum af b
for alle rækker med den samme a
Du foreslog at bruge følgende JOIN
for at gøre det:
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;
I modsætning til hvad du måske tror, er JOIN
vil ikke udføre en 1-1 JOIN
. Det er faktisk en mange-til-mange JOIN
siden som jeg sagde i går
du bruger ikke primær nøgle (heller ikke-null unik nøgle) i din join-klausul.
Faktisk omskriver den forespørgsel som SELECT
vil sandsynligvis hjælpe dig med at forstå problemet:
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
Som du vil se nu, rækken (1, null)
match (1, 1)
, (1, 2)
og (1, null)
. Afhængigt af den (ikke-deterministiske) rækkefølge for udførelse af forespørgslen, kan dette tildele en af de tre mulige værdier for b
(er ikke sikker på det, men måske endda opdatere det flere gange). I et vist omfang har du været heldig at finde det "forkerte" resultat, mens du testede!
Jeg håber, at dette forklarer lidt mere, hvorfor din forespørgsel ikke giver det forventede resultat. Siden multi-table UPDATE
sætninger tillader ikke ORDER BY
heller ikke GROUP BY
klausuler, som for mig selv, for at finde det "gode" resultat, ser jeg ikke mange andre muligheder end at finde minimum først gennem en underforespørgsel...