MySQL: Für jede Zeile in der Tabelle verändern, eine Zeile in einer anderen Tabelle
Ich habe zwei Tabellen :
SELECT * FROM data;
+----+---+---+
| id | c | g |
+----+---+---+
| 1 | 1 | 2 |
| 2 | 1 | 2 |
| 3 | 1 | 2 |
| 4 | 1 | 3 |
| 5 | 2 | 2 |
| 6 | 2 | 3 |
| 7 | 2 | 3 |
+----+---+---+
und
SELECT * FROM changes;
+----+-------+-------+---+
| id | c_old | c_new | g |
+----+-------+-------+---+
| 1 | 1 | 2 | 2 |
| 2 | 2 | 1 | 3 |
| 3 | 1 | 2 | 2 |
+----+-------+-------+---+
Für jede Zeile in changes
ich ändern muss exakt eine Zeile in data
wo data.g=changes.g and data.c=changes.c_old
. (davon ausgehen, dass es immer genug Streichhölzer)
Ich bin versucht, dies zu tun mit dieser Abfrage:
UPDATE
data INNER JOIN changes ON
data.c=changes.c_old AND p.g=changes.g
SET data.c_id=changes.c_new
WHERE data.id IN(
SELECT id FROM (
SELECT data.id from
data INNER JOIN changes ON
data.c=changes.c_old AND data.g=changes.g
GROUP BY changes.id
) AS another_table
)
Nun, ich bin überrascht, dass das Chaos eine Abfrage läuft. Aber, es nicht tut, was ich brauche. Die innerste select gibt diese Tabelle:
+----+
| id |
+----+
| 1 |
| 6 |
| 1 |
+----+
Beachten Sie, dass 1
erscheint zweimal. Das bedeutet, dass nur zwei Zeilen geändert wurde (Zeile 1 habe zweimal gewechselt), wenn ich Sie brauchte drei zu ändern. Gibt es eine Möglichkeit, sicherzustellen, dass jede id in das sub-query ist einzigartig? Gibt es einen besseren Weg, dies zu erreichen Schlamassel?
Vielen Dank im Voraus!
InformationsquelleAutor Luke | 2014-02-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wählen Sie ein Feld, das nicht Teil der group by-oder aggregieren.
Sollten Sie eine Aggregatfunktion auf die Daten.id in der select-oder Daten hinzufügen.id, um die groupby (obwohl ich vermute, dass ist nicht das gewünschte Ergebnis)
Dem INNER JOIN ist es in diesem dataset
1,2,3 erweitert sich durch mehrere Spiele in der Verknüpfung und 4,5 eliminiert werden, da kein match
Dann sind die Gruppierung von änderungen.id, die mit dem Ergebnis in (zeigt mit den Werten in der CSV-Liste nach der Gruppierung)
Da kein Aggregat oder deterministischen Art und Weise der Auswahl der Werte aus den verfügbaren Optionen, sind Sie immer die 1 von Daten.id gewählt, die für beide Veränderungen.id 1 und 3
Je nachdem, was Sie wollen, werden Sie wollen, 3 Zeilen? alle unterschiedlichen Werte? Sie sollte hinzufügen, dass deterministisches Verhalten zu wählen.
btw, ich bin mir ziemlich sicher, dass auch andere SQL-Motoren würde nicht zulassen, dass wählen (z.B. MSSQL), weil seine mehrdeutig. MySQL-Verhalten in dieser situation, ich glaube, es wählt den ersten Wert aus der ersten Zeile gespeichert, und so, warum bekommen Sie wahrscheinlich 1 in beiden Fällen, aber es ist frei zu wählen, was Wert, den es wünscht.
http://dev.mysql.com/doc/refman/5.7/en/group-by-extensions.html
changes
abgestimmt mit einer anderen Zeile indata
. Also, die Anzahl der zurückgegebenen Zeilen von der select-sollte gleich der Anzahl der Zeilen inchanges
und alle Werte von Daten.id sollte eindeutig sein. Tut mir Leid, das war nicht mehr klar. Wie man dem hinzufügen, dass deterministisches Verhalten, um die wählen Sie' wäre der Kern meiner Frage.Ich glaube, du bist fehlen einige Daten, um diese Unterscheidung. Die änderungen, die Tabelle ist ein Tupel (c.alt, c ist.g), von denen es nur 2 unterschiedliche Werte (1,2) und (2,3); Mit dem Tupel (1,2) es gibt 3 Spiele in Daten und für (2,3) es gibt 2 matches. Es klingt wie Sie sagen, für eines der Spiele (1,2) Sie möchten wählen Sie eine id (zum Beispiel Daten.id = 1) und für ein anderes match wählen (zum Beispiel Daten.id = 2); Sie müssen einen 3. Schlüssel zu uns auf, um zu verursachen, dass das Verhalten (wie eine rowid)
Auch, es scheint, Sie sind mit änderungen verfolgen, änderungen von Daten der Tabelle. Wenn das der Fall ist, sollten Sie einen Daten.id, um Ihre änderungen zu Tisch, und jetzt hätte Sie die eindeutige Kennung, um zu binden, um zurück zu dem Datensatz, der geändert wurde. So könnte Ihre 3. Säule zu erhalten Ihre separaten Zeile, obwohl dann gibt es keine Notwendigkeit zu verwenden die c.alt und c.g-Spalten für den Beitritt, weil Sie den Primärschlüssel id von der Tabelle mit Daten in Ihre Veränderungen Tabelle. Versuchen Sie, zu verfolgen, für langsam veränderliche Dimensionen oder ändern Sie Werte der Datensätze in Daten?
Vielen Dank für Ihre Kommentare. Sie haben mir geholfen, denke über mein problem in mehr Tiefe, obwohl ich kann nicht finden eine Lösung. Ich versuche dies als eine mögliche Lösungen für eine dieser Frage, die ich gepostet. Die Serie der updates eingereicht individuell produziert das gewünschte Ergebnis, aber ist zu langsam. Ich wollte versuchen 1.
create temporary table changes
, 2.insert
alle änderungen als batch, 3. dieses update durchführen, 4.drop temporary table
. Also, ich weiß nicht, dieid
s der Zeilen, die ich ändern will.Sie gehen zu müssen, erhalten Sie eine eindeutige Kennung für das, was Sie wollen, Sie zu aktualisieren, vor allem, wenn Sie wollen, um batch-updates. Sie sind im wesentlichen bauen zu wollen, eine Liste der änderungen in eine temporäre Tabelle, und führen Sie ein batch-update in regelmäßigen Abständen aus dieser Tabelle ist, im Gegensatz zu der Ausführung von einzelnen update-Befehle gleichzeitig. Sie sagen, Sie wissen nicht, die ids der Zeilen, die Sie ändern möchten, aber Sie sind in Ordnung, nur mit wechselnden, willkürlich eine der Instanzen der Tupel in der Daten? Warum erlauben sogar die doppelte Instanzen in den Daten, wenn das ist der Fall?
InformationsquelleAutor mhoglan
Teilen den Prozess in zwei Aufgaben:
id
von der zu aktualisierenden Zeilen indata
und den Wert zu setzenc
.Aufgabe 1 kann erreicht werden, indem Sie die folgende Abfrage (beachten Sie die Verwendung von
distinct
um loszuwerden, Duplikate):Sollten Sie auf die folgenden:
Nun für das update verwenden Sie einfach die vorherigen Abfrage als abgeleitete Tabelle-Ausdruck und kommen Sie zu
data
:Und Sie sind fertig, Ergebnis:
id
s in derdata
verändert wird. Es waren nur drei Zeilen inchanges
so, nur drei Zeilen indata
geändert werden müssen.InformationsquelleAutor Xint0