Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MYSQL Join-Update interne Schritte

Für die "Abfrage, die die Zeilen nicht korrekt aktualisiert":

Sie möchten Spalte b aktualisieren auf das Minimum von b für alle Zeilen mit demselben a

Sie haben vorgeschlagen, den folgenden JOIN zu verwenden dazu:

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;

Im Gegensatz zu dem, was Sie vielleicht denken, das JOIN führt kein 1-1 JOIN durch . Es ist tatsächlich ein Viele-zu-Viele JOIN seit wie ich gestern sagte Sie verwenden in Ihrer Join-Klausel keinen Primärschlüssel (und keinen eindeutigen Nicht-Null-Schlüssel).

Umschreiben dieser Abfrage tatsächlich als SELECT wird Ihnen wahrscheinlich helfen, das Problem zu verstehen:

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

Wie Sie jetzt sehen werden, ist die Zeile (1, null) Übereinstimmung mit (1, 1) , (1, 2) und (1, null) . Abhängig von der (nicht deterministischen) Ausführungsreihenfolge der Abfrage kann dies einen der drei möglichen Werte für b zuweisen (Da bin ich mir nicht sicher, aber vielleicht sogar mehrere aktualisieren mal). Bis zu einem gewissen Grad hatten Sie Glück, beim Testen das "falsche" Ergebnis zu finden!

Ich hoffe, dies erklärt ein wenig mehr, warum Ihre Abfrage nicht das erwartete Ergebnis liefert. Seit Multi-Table UPDATE Anweisungen erlauben ORDER BY nicht noch GROUP BY Klauseln, um das "gute" Ergebnis zu finden, sehe ich nicht viele andere Möglichkeiten, als zuerst das Minimum zu finden durch eine Unterabfrage...