Ich habe eine MySQL-Tabelle mit Koordinaten, die Spaltennamen sind X und Y. Jetzt möchte ich die Spaltenwerte in dieser Tabelle vertauschen, sodass X zu Y und Y zu X wird. Die naheliegendste Lösung wäre, die Spalten umzubenennen, aber ich Ich möchte keine Strukturänderungen vornehmen, da ich nicht unbedingt die Berechtigung dazu habe.
Ist dies in irgendeiner Weise mit UPDATE möglich ? UPDATE-Tabelle SET X = Y, Y = X macht offensichtlich nicht das, was ich will.
Bearbeiten: Bitte beachten Sie, dass meine oben erwähnte Einschränkung der Berechtigungen die Verwendung von ALTER TABLE oder anderen Befehlen, die die Tabellen- / Datenbankstruktur ändern, effektiv verhindert. Das Umbenennen oder Hinzufügen neuer Spalten ist leider keine Option.
UPDATE table SET X = Y, Y = X
Ist die Standardmethode in SQL, nur MySQL verhält sich schlecht.Antworten:
Ich musste mich nur damit befassen und werde meine Ergebnisse zusammenfassen.
Der
UPDATE table SET X=Y, Y=X
Ansatz funktioniert offensichtlich nicht, da nur beide Werte auf Y gesetzt werden.Hier ist eine Methode, die eine temporäre Variable verwendet. Vielen Dank an Antony aus den Kommentaren von http://beerpla.net/2009/02/17/swapping-column-values-in-mysql/ für die Optimierung "IS NOT NULL". Ohne sie funktioniert die Abfrage unvorhersehbar. Siehe das Tabellenschema am Ende des Beitrags. Diese Methode tauscht die Werte nicht aus, wenn einer von ihnen NULL ist. Verwenden Sie Methode 3, die diese Einschränkung nicht aufweist.
UPDATE swap_test SET x=y, y=@temp WHERE (@temp:=x) IS NOT NULL;
Diese Methode wurde von Dipin erneut in den Kommentaren von http://beerpla.net/2009/02/17/swapping-column-values-in-mysql/ angeboten . Ich denke, es ist die eleganteste und sauberste Lösung. Es funktioniert sowohl mit NULL- als auch mit Nicht-NULL-Werten.
UPDATE swap_test SET x=(@temp:=x), x = y, y = @temp;
Ein anderer Ansatz, den ich mir ausgedacht habe, scheint zu funktionieren:
UPDATE swap_test s1, swap_test s2 SET s1.x=s1.y, s1.y=s2.x WHERE s1.id=s2.id;
Im Wesentlichen wird die 1. Tabelle aktualisiert und die 2. Tabelle wird zum Abrufen der alten Daten verwendet.
Beachten Sie, dass für diesen Ansatz ein Primärschlüssel erforderlich sein muss.
Dies ist mein Testschema:
quelle
Sie können die Summe nehmen und den entgegengesetzten Wert mit X und Y subtrahieren
Hier ist ein Beispieltest (und er funktioniert mit negativen Zahlen)
Hier wird der Tausch durchgeführt
Versuche es !!!
quelle
TINYINT
oder riesige Valules vonINT
, du hast recht !!!Der folgende Code funktioniert für alle Szenarien in meinen Schnelltests:
quelle
UPDATE table swap_test
? Sollte es nicht seinUPDATE swap_test
?UPDATE-Tabelle SET X = Y, Y = X. macht genau das, was Sie wollen (bearbeiten: in PostgreSQL, nicht in MySQL, siehe unten). Die Werte werden aus der alten Zeile übernommen und einer neuen Kopie derselben Zeile zugewiesen. Anschließend wird die alte Zeile ersetzt. Sie müssen nicht auf eine temporäre Tabelle, eine temporäre Spalte oder andere Swap-Tricks zurückgreifen.
@ D4V360: Ich verstehe. Das ist schockierend und unerwartet. Ich benutze PostgreSQL und meine Antwort funktioniert dort korrekt (ich habe es versucht). In den PostgreSQL UPDATE-Dokumenten (unter Parameter, Ausdruck) wird erwähnt, dass Ausdrücke auf der rechten Seite der SET-Klauseln explizit die alten Werte von Spalten verwenden. Ich sehe, dass die entsprechenden MySQL UPDATE-Dokumente die Anweisung "UPDATE-Zuweisungen für einzelne Tabellen werden im Allgemeinen von links nach rechts ausgewertet" enthalten, die das von Ihnen beschriebene Verhalten impliziert.
Gut zu wissen.
quelle
Ok, nur zum Spaß kannst du das machen! (vorausgesetzt, Sie tauschen Zeichenfolgenwerte aus)
Ein bisschen Spaß beim Missbrauch des Evaluierungsprozesses von links nach rechts in MySQL.
Alternativ können Sie auch einfach XOR verwenden, wenn es sich um Zahlen handelt. Sie haben Koordinaten erwähnt. Haben Sie also schöne ganzzahlige Werte oder komplexe Zeichenfolgen?
Edit: Das XOR-Zeug funktioniert übrigens so:
quelle
Ich glaube, eine Zwischenaustauschvariable ist die beste Vorgehensweise auf diese Weise:
Erstens funktioniert es immer; Zweitens funktioniert es unabhängig vom Datentyp.
Trotz beidem
und
arbeiten normalerweise nur für den Datentyp Nummer, und es liegt in Ihrer Verantwortung, einen Überlauf zu verhindern. Sie können XOR nicht zwischen vorzeichenbehaftet und vorzeichenlos verwenden. Sie können auch keine Summe für die Überlaufmöglichkeit verwenden.
Und
funktioniert nicht, wenn c1 0 oder NULL oder eine Zeichenfolge mit der Länge Null oder nur Leerzeichen ist.
Wir müssen es ändern
Hier sind die Skripte:
quelle
Zwei Alternativen 1. Verwenden Sie eine temporäre Tabelle. 2. Untersuchen Sie den XOR-Algorithmus
quelle
Etwas wie das?Edit: Über Gregs Kommentar: Nein, das funktioniert nicht:
quelle
Das funktioniert sicher! Ich habe es nur gebraucht, um Euro- und SKK-Preisspalten zu tauschen. :) :)
Dies funktioniert nicht (FEHLER 1064 (42000): Sie haben einen Fehler in Ihrer SQL-Syntax).
quelle
Angenommen, Sie haben Ganzzahlen in Ihren Spalten signiert, müssen Sie möglicherweise CAST (a ^ b AS SIGNED) verwenden, da das Ergebnis des Operators ^ eine vorzeichenlose 64-Bit-Ganzzahl in MySQL ist.
Falls es jemandem hilft, hier ist die Methode, mit der ich dieselbe Spalte zwischen zwei angegebenen Zeilen ausgetauscht habe:
Dabei sind $ 1 und $ 2 die Schlüssel zweier Zeilen und $ 3 das Ergebnis der ersten Abfrage.
quelle
Ich habe es aber nicht versucht
Könnte es tun.
Kennzeichen
quelle
Sie könnten Spaltennamen ändern, aber dies ist eher ein Hack. Seien Sie jedoch vorsichtig mit Indizes, die sich möglicherweise in diesen Spalten befinden
quelle
Tabellenname ist Kunde. Felder sind a und b, tauschen Sie einen Wert gegen b;.
UPDATE Kunde SET a = (@ temp: = a), a = b, b = @temp
Ich habe überprüft, ob dies gut funktioniert.
quelle
In SQL Server können Sie diese Abfrage verwenden:
quelle
Vertauschen von Spaltenwerten mit einer einzelnen Abfrage
UPDATE my_table SET a = @ tmp: = a, a = b, b = @ tmp;
Prost...!
quelle
Ich musste nur den Wert von einer Spalte in die andere verschieben (wie beim Archivieren) und den Wert der ursprünglichen Spalte zurücksetzen.
Das Folgende (Referenz von # 3 aus der oben akzeptierten Antwort) hat für mich funktioniert.
quelle
quelle
In diesem Beispiel werden start_date und end_date gegen Datensätze ausgetauscht, bei denen die Daten falsch herum sind (bei der Durchführung einer ETL-Umschreibung wurden einige Startdaten später als am Ende gefunden Termine. Runter, schlechte Programmierer!).
In situ verwende ich MEDIUMINTs aus Leistungsgründen (wie julianische Tage, aber mit einer 0-Wurzel von 1900-01-01), daher war es in Ordnung, eine Bedingung von WHERE mdu.start_date> mdu.end_date auszuführen .
Die PKs befanden sich in allen drei Spalten einzeln (aus betrieblichen / indizierenden Gründen).
quelle
Angenommen, Sie möchten den Wert von Vor- und Nachname in tb_user austauschen.
Das sicherste wäre:
quelle
Sie können unten Abfrage anwenden, es hat perfekt für mich funktioniert.
quelle