sql >> Databasteknik >  >> RDS >> Mysql

MYSQL gå med i uppdateringens interna steg

För "frågan uppdateras inte korrekt raderna":

Du vill uppdatera kolumn b till minimum av b för alla rader som har samma a

Du föreslog att du skulle använda följande JOIN för att göra 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;

Tvärtemot vad du kanske tror, ​​att JOIN kommer inte att utföra en 1-1 JOIN . Det är faktiskt en många-till-många JOIN sedan som jag sa igår du använder inte primärnyckel (eller icke-null unik nyckel) i din join-klausul.

Faktum är att skriva om den frågan som SELECT kommer förmodligen att hjälpa dig att förstå 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 kommer att se nu, raden (1, null) matcha (1, 1) , (1, 2) och (1, null) . Beroende på den (icke-deterministiska) exekveringsordningen för frågan, kan detta tilldela något av de tre möjliga värdena för b (är inte säker på det, men kanske även uppdatera den flera gånger). Till viss del har du haft turen att hitta "fel" resultat när du testade!

Jag hoppas att detta förklarar lite mer varför din fråga inte ger det förväntade resultatet. Sedan multi-table UPDATE satser tillåter inte ORDER BY inte heller GROUP BY klausuler, för att hitta det "bra" resultatet, ser jag inte många andra alternativ än att hitta minsta först genom en underfråga...



  1. CREATE DATABASE-frågan med java jdbc och förberedd sats returnerar syntaxfel

  2. SQL Server-felhantering:undantag och databasklientkontraktet

  3. Objektorienterade strukturer i relationsdatabaser

  4. Det går inte att ansluta till PostgreSQL-servern