Mehrere Updates in MySQL

388

Ich weiß, dass Sie mehrere Zeilen gleichzeitig einfügen können. Gibt es eine Möglichkeit, mehrere Zeilen gleichzeitig (wie in einer Abfrage) in MySQL zu aktualisieren?

Bearbeiten: Zum Beispiel habe ich folgendes

Name   id  Col1  Col2
Row1   1    6     1
Row2   2    2     3
Row3   3    9     5
Row4   4    16    8

Ich möchte alle folgenden Updates in einer Abfrage zusammenfassen

UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;
Teifion
quelle

Antworten:

651

Ja, das ist möglich - Sie können INSERT ... ON DUPLICATE KEY UPDATE verwenden.

Anhand Ihres Beispiels:

INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);
Michiel de Mare
quelle
22
Wenn es keine Duplikate gibt, möchte ich nicht, dass diese Zeile eingefügt wird. Was soll ich tun? weil ich Informationen von einer anderen Site abrufe, die Tabellen mit IDs verwaltet. Ich füge Werte in Bezug auf diese ID ein. Wenn die Site neue Datensätze hat, füge ich am Ende nur die IDs ein und zähle mit Ausnahme aller anderen Informationen. Wenn und nur wenn es einen Eintrag für die ID gibt, sollte sie aktualisiert werden, andernfalls sollte sie überspringen. was soll ich tun?
Jayapal Chandran
33
Hinweis: Diese Antwort setzt auch voraus, dass ID der Primärschlüssel ist
JM4
11
@ JayapalChandran Sie sollten INSERT IGNORE zusammen mit ON DUPLICATE KEY UPDATE verwenden. dev.mysql.com/doc/refman/5.5/en/insert.html
Haralan Dobrev
16
@HaralanDobrev Mit INSERT IGNORE werden weiterhin die nicht duplizierten Datensätze eingefügt. was Jayapal vermeiden wollte. INSERT IGNORE verwandelt Fehler in Warnungen :( stackoverflow.com/questions/548541/…
Takehiro Adachi
2
Bei dieser Antwort wird davon ausgegangen, dass die ID ein eindeutiger Schlüssel ist (kann, wie andere sagten, primär sein). Noch wichtiger ist jedoch, dass keine anderen eindeutigen Schlüssel vorhanden sind. Wenn es welche gibt, kann es einen Schraubenschlüssel in die Werke werfen.
Steve Horvath
129

Da Sie dynamische Werte haben, müssen Sie für die zu aktualisierenden Spalten eine IF oder CASE verwenden. Es wird ein bisschen hässlich, aber es sollte funktionieren.

Anhand Ihres Beispiels können Sie Folgendes tun:

UPDATE-Tabelle SET Col1 = CASE-ID 
                          WENN 1 DANN 1 
                          WENN 2 DANN 2 
                          WENN 4 DANN 10 
                          SONST Col1 
                        ENDE, 
                 Col2 = CASE id 
                          WENN 3 DANN 3 
                          WENN 4 DANN 12 
                          SONST Col2 
                        ENDE
             WHERE id IN (1, 2, 3, 4);
Harrison Fisk
quelle
vielleicht nicht so hübsch für dynamische Aktualisierungen zu schreiben, aber interessanter Blick auf die Funktionalität des Gehäuses ...
me_
1
@ user2536953, es kann auch für die dynamische Aktualisierung hilfreich sein. Zum Beispiel habe ich diese Lösung in Schleife in PHP verwendet:$commandTxt = 'UPDATE operations SET chunk_finished = CASE id '; foreach ($blockOperationChecked as $operationID => $operationChecked) $commandTxt .= " WHEN $operationID THEN $operationChecked "; $commandTxt .= 'ELSE id END WHERE id IN ('.implode(', ', array_keys(blockOperationChecked )).');';
Boolean_Type
86

Die Frage ist alt, aber ich möchte das Thema mit einer anderen Antwort erweitern.

Mein Punkt ist, der einfachste Weg, dies zu erreichen, besteht darin, mehrere Abfragen mit einer Transaktion zu versehen. Die akzeptierte Antwort INSERT ... ON DUPLICATE KEY UPDATEist ein netter Hack, aber man sollte sich seiner Nachteile und Einschränkungen bewusst sein:

  • Wie gesagt, wenn Sie die Abfrage mit Zeilen starten, deren Primärschlüssel nicht in der Tabelle vorhanden sind, fügt die Abfrage neue "halbgebackene" Datensätze ein. Wahrscheinlich ist es nicht das, was du willst
  • Wenn Sie eine Tabelle mit einem Feld ungleich Null ohne Standardwert haben und dieses Feld in der Abfrage nicht berühren möchten, wird eine "Field 'fieldname' doesn't have a default value"MySQL-Warnung angezeigt, auch wenn Sie überhaupt keine einzelne Zeile einfügen. Es wird Sie in Schwierigkeiten bringen, wenn Sie sich dazu entschließen, streng zu sein und MySQL-Warnungen in Laufzeitausnahmen in Ihrer App umzuwandeln.

Ich habe einige Leistungstests für drei der vorgeschlagenen Varianten durchgeführt, einschließlich der INSERT ... ON DUPLICATE KEY UPDATEVariante, einer Variante mit der Klausel "case / when / then" und einem naiven Ansatz mit Transaktion. Sie können die Python - Code und die Ergebnisse bekommen hier . Die allgemeine Schlussfolgerung ist, dass die Variante mit case-Anweisung doppelt so schnell ist wie zwei andere Varianten, aber es ist ziemlich schwierig, korrekten und injektionssicheren Code dafür zu schreiben. Ich persönlich halte mich daher an den einfachsten Ansatz: die Verwendung von Transaktionen.

Bearbeiten: Die Ergebnisse von Dakusan beweisen, dass meine Leistungsschätzungen nicht ganz gültig sind. Bitte sehen Sie diese Antwort für eine weitere, ausführlichere Untersuchung.

Roman Imankulov
quelle
Mit Transaktionen, sehr schöner (und einfacher) Tipp!
mTorres
Was ist, wenn meine Tabellen nicht vom Typ InnoDB sind?
TomeeNS
1
Könnte jemand einen Link zu den Transaktionen bereitstellen, wie dies aussehen soll? Und / oder Code für einen einspritzsicheren Code für die Variante mit case-Anweisung?
François M.
1
Ich finde die Informationen zur Geschwindigkeit in diesem Beitrag falsch. Ich habe darüber in einem Beitrag unten geschrieben. stackoverflow.com/questions/3432/multiple-updates-in-mysql/…
Dakusan
1
@ Dakusan, tolle Antwort. Vielen Dank für das Erweitern, Kommentieren und Korrigieren meiner Ergebnisse.
Roman Imankulov
72

Nicht sicher, warum eine andere nützliche Option noch nicht erwähnt wird:

UPDATE my_table m
JOIN (
    SELECT 1 as id, 10 as _col1, 20 as _col2
    UNION ALL
    SELECT 2, 5, 10
    UNION ALL
    SELECT 3, 15, 30
) vals ON m.id = vals.id
SET col1 = _col1, col2 = _col2;
Newtover
quelle
4
Das ist das beste. Vor allem, wenn Sie die Werte für die Aktualisierung aus einer anderen SQL-Abfrage ziehen, wie ich es getan habe.
v010dya
1
Dies war großartig für ein Update einer Tabelle mit einer großen Anzahl von Spalten. Ich werde diese Abfrage wahrscheinlich in Zukunft häufig verwenden. Vielen Dank!
Casper Wilkes
Ich habe diese Art von Abfrage versucht. Aber wenn die Datensätze 30.000 erreichen, wird der Grenzserver gestoppt. Gibt es eine andere Lösung?
Bhavin Chauhan
Das sieht gut aus. Ich werde versuchen, dies mit einer WHERE-Klausel zu kombinieren, bei der die Primärschlüssel nicht aktualisiert, sondern zur Identifizierung der zu ändernden Spalten verwendet werden.
nl-x
@BhavinChauhan Haben Sie versucht, eine temporäre Tabelle anstelle der Join-Auswahl zu verwenden, um das Problem zu umgehen?
nl-x
41

Für InnoDB gilt Folgendes.

Ich halte es für wichtig, die Geschwindigkeit der drei verschiedenen Methoden zu kennen.

Es gibt 3 Methoden:

  1. INSERT: INSERT mit ON DUPLICATE KEY UPDATE
  2. TRANSAKTION: Hier führen Sie eine Aktualisierung für jeden Datensatz innerhalb einer Transaktion durch
  3. FALL: In welchem ​​Fall / wann Sie für jeden unterschiedlichen Datensatz innerhalb eines UPDATE einen Fall / wann

Ich habe das gerade getestet und die INSERT-Methode war für mich 6,7-mal schneller als die TRANSACTION-Methode. Ich habe sowohl 3.000 als auch 30.000 Zeilen ausprobiert.

Die TRANSACTION-Methode muss weiterhin jede einzelne Abfrage ausführen, was einige Zeit in Anspruch nimmt, obwohl sie die Ergebnisse während der Ausführung im Speicher oder so stapelt. Die TRANSACTION-Methode ist sowohl in Replikations- als auch in Abfrageprotokollen ziemlich teuer.

Schlimmer noch, die CASE-Methode war 41,1-mal langsamer als die INSERT-Methode mit 30.000 Datensätzen (6,1-mal langsamer als TRANSACTION). Und 75x langsamer in MyISAM. Die INSERT- und CASE-Methoden haben bei ~ 1.000 Datensätzen die Gewinnschwelle überschritten. Selbst bei 100 Datensätzen ist die CASE-Methode kaum schneller.

Im Allgemeinen halte ich die INSERT-Methode für die beste und einfachste Anwendung. Die Abfragen sind kleiner und leichter zu lesen und nehmen nur eine Aktionsabfrage auf. Dies gilt sowohl für InnoDB als auch für MyISAM.

Bonusmaterial:

Die Lösung für das Problem des INSERT-Nicht-Standardfelds besteht darin, die relevanten SQL-Modi vorübergehend auszuschalten : SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES",""). Stellen Sie sicher, sql_modedass Sie die erste speichern, wenn Sie sie zurücksetzen möchten.

Was andere Kommentare betrifft, die besagen, dass das auto_increment mit der INSERT-Methode hochgefahren wird, scheint dies in InnoDB der Fall zu sein, nicht jedoch in MyISAM.

Der Code zum Ausführen der Tests lautet wie folgt. Es gibt auch .SQL-Dateien aus, um den Overhead des PHP-Interpreters zu beseitigen

<?
//Variables
$NumRows=30000;

//These 2 functions need to be filled in
function InitSQL()
{

}
function RunSQLQuery($Q)
{

}

//Run the 3 tests
InitSQL();
for($i=0;$i<3;$i++)
    RunTest($i, $NumRows);

function RunTest($TestNum, $NumRows)
{
    $TheQueries=Array();
    $DoQuery=function($Query) use (&$TheQueries)
    {
        RunSQLQuery($Query);
        $TheQueries[]=$Query;
    };

    $TableName='Test';
    $DoQuery('DROP TABLE IF EXISTS '.$TableName);
    $DoQuery('CREATE TABLE '.$TableName.' (i1 int NOT NULL AUTO_INCREMENT, i2 int NOT NULL, primary key (i1)) ENGINE=InnoDB');
    $DoQuery('INSERT INTO '.$TableName.' (i2) VALUES ('.implode('), (', range(2, $NumRows+1)).')');

    if($TestNum==0)
    {
        $TestName='Transaction';
        $Start=microtime(true);
        $DoQuery('START TRANSACTION');
        for($i=1;$i<=$NumRows;$i++)
            $DoQuery('UPDATE '.$TableName.' SET i2='.(($i+5)*1000).' WHERE i1='.$i);
        $DoQuery('COMMIT');
    }

    if($TestNum==1)
    {
        $TestName='Insert';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf("(%d,%d)", $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery('INSERT INTO '.$TableName.' VALUES '.implode(', ', $Query).' ON DUPLICATE KEY UPDATE i2=VALUES(i2)');
    }

    if($TestNum==2)
    {
        $TestName='Case';
        $Query=Array();
        for($i=1;$i<=$NumRows;$i++)
            $Query[]=sprintf('WHEN %d THEN %d', $i, (($i+5)*1000));
        $Start=microtime(true);
        $DoQuery("UPDATE $TableName SET i2=CASE i1\n".implode("\n", $Query)."\nEND\nWHERE i1 IN (".implode(',', range(1, $NumRows)).')');
    }

    print "$TestName: ".(microtime(true)-$Start)."<br>\n";

    file_put_contents("./$TestName.sql", implode(";\n", $TheQueries).';');
}
Dakusan
quelle
1
Du machst hier die Arbeit des Herrn;) Sehr geschätzt.
Chili
Beim Testen der Leistung zwischen GoLang und PHP mit 40.000 Zeilen in MariaDB erhielt ich 2 Sekunden in PHP und mehr als 6 Sekunden in Golang. Nun, mir wurde immer gesagt, dass GoLang schneller als PHP laufen würde !!! Also frage ich mich, wie ich die Leistung verbessern kann ... Mit INSERT ... ON DUPLICATE KEY UPDATE ... habe ich 0,74 Sekunden auf Golang und 0,86 Sekunden auf PHP !!!!
Diego Favero
1
Der Sinn meines Codes besteht darin, die Timing-Ergebnisse ausschließlich auf die SQL-Anweisungen und nicht auf den Code für die Sprache oder die Bibliotheken zu beschränken. GoLang und PHP sind zwei völlig getrennte Sprachen, die für ganz unterschiedliche Dinge gedacht sind. PHP ist für eine Single-Run-Scripting-Umgebung auf einem einzelnen Thread mit meist begrenzter und passiver Garbage Collection gedacht. GoLang ist für lange laufende kompilierte Anwendungen mit aggressiver Speicherbereinigung und Multithreading als einer der wichtigsten Sprachfunktionen gedacht. Sie könnten in Bezug auf Sprachfunktionalität und Vernunft kaum unterschiedlicher sein. [Fortsetzung]
Dakusan
Stellen Sie daher beim Ausführen Ihrer Tests sicher, dass die Geschwindigkeitsmessungen ausschließlich auf die Funktionsaufrufe "Abfrage" für die SQL-Anweisung beschränkt sind. Das Vergleichen und Optimieren der anderen Teile des Quellcodes, die nicht ausschließlich der Abfrageaufruf sind, ähnelt dem Vergleichen von Äpfeln und Orangen. Wenn Sie Ihre Ergebnisse darauf beschränken (die Zeichenfolgen müssen vorkompiliert und einsatzbereit sein), sollten die Ergebnisse sehr ähnlich sein. Alle Unterschiede zu diesem Zeitpunkt sind auf die SQL-Bibliothek der Sprache zurückzuführen und nicht unbedingt auf die Sprache selbst. Meiner Meinung nach war und bleibt die Lösung INSERT ON DUPLICATE die beste Option. [Fortsetzung]
Dakusan
Was Ihren Kommentar zu GoLang betrifft, der schneller ist, so ist dies eine unglaublich breite Aussage, die keine der zahlreichen Vorbehalte oder Nuancen dieser Sprachen und ihrer Designs berücksichtigt. Java ist eine interpretierte Sprache, aber ich habe vor 15 Jahren herausgefunden, dass sie in bestimmten Szenarien tatsächlich fast C-Geschwindigkeit erreichen (und vielleicht sogar manchmal übertreffen) kann. Und C ist eine kompilierte Sprache und neben Assembler die häufigste der Systemsprachen der untersten Ebene. Ich liebe wirklich, was GoLang tut und es hat definitiv die Kraft und Fließfähigkeit, eines der gängigsten Systeme zu werden und [Cont]
Dakusan
9

Verwenden Sie eine temporäre Tabelle

// Reorder items
function update_items_tempdb(&$items)
{
    shuffle($items);
    $table_name = uniqid('tmp_test_');
    $sql = "CREATE TEMPORARY TABLE `$table_name` ("
        ."  `id` int(10) unsigned NOT NULL AUTO_INCREMENT"
        .", `position` int(10) unsigned NOT NULL"
        .", PRIMARY KEY (`id`)"
        .") ENGINE = MEMORY";
    query($sql);
    $i = 0;
    $sql = '';
    foreach ($items as &$item)
    {
        $item->position = $i++;
        $sql .= ($sql ? ', ' : '')."({$item->id}, {$item->position})";
    }
    if ($sql)
    {
        query("INSERT INTO `$table_name` (id, position) VALUES $sql");
        $sql = "UPDATE `test`, `$table_name` SET `test`.position = `$table_name`.position"
            ." WHERE `$table_name`.id = `test`.id";
        query($sql);
    }
    query("DROP TABLE `$table_name`");
}
Laie
quelle
8
UPDATE table1, table2 SET table1.col1='value', table2.col1='value' WHERE table1.col3='567' AND table2.col6='567'

Das sollte für dich funktionieren.

Das MySQL-Handbuch enthält eine Referenz für mehrere Tabellen.

UnkwnTech
quelle
6

Warum erwähnt niemand mehrere Anweisungen in einer Abfrage ?

In PHP verwenden Sie die multi_queryMethode der MySQL-Instanz.

Aus dem PHP-Handbuch

MySQL erlaubt optional mehrere Anweisungen in einer Anweisungszeichenfolge. Das gleichzeitige Senden mehrerer Anweisungen reduziert Client-Server-Roundtrips, erfordert jedoch eine spezielle Behandlung.

Hier ist das Ergebnis im Vergleich zu anderen 3 Methoden in Update 30.000 Raw. Code kann gefunden werden hier die auf Antwort von @Dakusan basiert

Transaktion: 5.5194580554962
Einfügen: 0.20669293403625
Fall: 16.474853992462
Multi: 0.0412278175354

Wie Sie sehen können, ist die Abfrage mehrerer Anweisungen effizienter als die höchste Antwort.

Wenn Sie folgende Fehlermeldung erhalten:

PHP Warning:  Error while sending SET_OPTION packet

Möglicherweise müssen Sie die max_allowed_packetMySQL-Konfigurationsdatei auf meinem Computer erhöhen /etc/mysql/my.cnfund dann MySQL neu starten.

Mononoke
quelle
Alle folgenden Vergleiche werden gegen den INSERT-Test durchgeführt. Ich lief den Test unter den gleichen Bedingungen und ohne Transaktionen war es 145x langsamer auf 300 Zeilen und 753x langsamer für 3000 Zeilen. Ich hatte ursprünglich mit den 30.000 Reihen angefangen, aber ich machte mir das Mittagessen und kam zurück und es ging immer noch. Dies ist sinnvoll, da es lächerlich teuer wäre, einzelne Abfragen auszuführen und jede einzeln in die Datenbank zu leeren. Besonders bei der Replikation. Das Aktivieren von Transaktionen macht jedoch einen großen Unterschied. Bei 3.000 Zeilen dauerte es 1,5x mehr und bei 30.000 Zeilen 2,34x . [Fortsetzung]
Dakusan
Aber Sie hatten Recht damit, dass es schnell ging (mit Transaktionen). Bei 3.000 und 30.000 Zeilen war es schneller als alles andere als die INSERT-Methode. Es gibt absolut keine Möglichkeit, mit der Ausführung einer Abfrage bessere Ergebnisse zu erzielen als mit 30.000 Abfragen, selbst wenn diese in einem speziellen MySQL-API-Aufruf gestapelt werden. Mit nur 300 Zeilen war es VIEL schneller als alle anderen Methoden (zu meiner Überraschung), was ungefähr der gleichen Grafikkurve wie die CASE-Methode folgt. Dies kann auf zwei Arten erklärt werden. Das erste ist, dass die INSERT-Methode aufgrund des "ON DUPLICATE KEY [cont]
Dakusan
UPDATE "verursacht sowohl ein" INSERT "als auch ein" UPDATE ". Das andere ist, dass es im SQL-Prozessor aufgrund von Indexsuchen weniger Arbeit kostet, jeweils nur eine Zeile zu bearbeiten. Ich bin mir nicht sicher, wie Sie andere Ergebnisse erzielt haben als ich. Aber Ihr zusätzlicher Test sieht solide aus. Ich bin mir nicht einmal sicher, wie die Replikation mit diesem Aufruf umgehen würde. Dies würde auch nur für UPDATE-Aufrufe
funktionieren
Ich habe 300 UPDATEs gleichzeitig für eine Tabelle ausgeführt, um einen Fehler innerhalb einer for-Schleife zu korrigieren, die 41 Sekunden dauerte. Das Einfügen derselben UPDATE-Abfragen in eine $mysqli->multi_query($sql)dauerte "0" Sekunden. Nachfolgende Abfragen schlugen jedoch fehl, sodass ich dies zu einem separaten "Programm" machte.
Chris K
Vielen Dank. Konnte in einer Minute etwa 5.000 Zeilen (nicht mehr getestet) mithilfe mehrerer Abfragen aktualisieren. Wenn jemand nach einer PDO-Lösung sucht: stackoverflow.com/questions/6346674/…
Scofield
3

Sie können eine Einstellung namens "Multi-Anweisung" ändern, die den implementierten "Sicherheitsmechanismus" von MySQL deaktiviert, um (mehr als einen) Injektionsbefehl zu verhindern. Typisch für die "brillante" Implementierung von MySQL, verhindert es auch, dass Benutzer effiziente Abfragen durchführen.

Hier ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) finden Sie einige Informationen zur C-Implementierung der Einstellung.

Wenn Sie PHP verwenden, können Sie mit mysqli mehrere Anweisungen ausführen (ich glaube, php wird bereits seit einiger Zeit mit mysqli ausgeliefert).

$con = new mysqli('localhost','user1','password','my_database');
$query = "Update MyTable SET col1='some value' WHERE id=1 LIMIT 1;";
$query .= "UPDATE MyTable SET col1='other value' WHERE id=2 LIMIT 1;";
//etc
$con->multi_query($query);
$con->close();

Ich hoffe, das hilft.

Brooks
quelle
4
Dies entspricht dem separaten Senden der Abfragen. Der einzige Unterschied besteht darin, dass Sie alles in einem Netzwerkpaket senden, die UPDATEs jedoch weiterhin als separate Abfragen verarbeitet werden. Besser ist es, sie in eine Transaktion zu packen, dann werden die Änderungen sofort in die Tabelle übernommen.
Marki555
3
Wie verpacke ich sie in eine Transaktion? Zeigen Sie uns bitte.
TomeeNS
@TomeeNS mysqli::begin_transaction(..)Vor und mysql::commit(..)nach dem Senden der Abfrage verwenden . Oder verwenden Sie START TRANSACTIONals erste und COMMITals letzte Anweisung in der Abfrage selbst.
Juha Palomäki
3

Sie können dieselbe Tabelle als Alias ​​verwenden, um die IDs anzugeben, nach denen Sie einfügen möchten (wenn Sie eine zeilenweise Aktualisierung durchführen:

UPDATE table1 tab1, table1 tab2 -- alias references the same table
SET 
col1 = 1
,col2 = 2
. . . 
WHERE 
tab1.id = tab2.id;

Darüber hinaus sollte es offensichtlich sein, dass Sie auch von anderen Tabellen aus aktualisieren können. In diesem Fall wird das Update auch als "SELECT" -Anweisung verwendet, sodass Sie die Daten aus der von Ihnen angegebenen Tabelle erhalten. Sie geben in Ihrer Abfrage explizit die Aktualisierungswerte an, sodass die zweite Tabelle nicht betroffen ist.

Eierwaren
quelle
2

Möglicherweise möchten Sie auch Joins für Updates verwenden, was ebenfalls möglich ist.

Update someTable Set someValue = 4 From someTable s Inner Join anotherTable a on s.id = a.id Where a.id = 4
-- Only updates someValue in someTable who has a foreign key on anotherTable with a value of 4.

Bearbeiten: Wenn die Werte, die Sie aktualisieren, nicht von einer anderen Stelle in der Datenbank stammen, müssen Sie mehrere Aktualisierungsabfragen ausführen.

Shawn
quelle
1

Und jetzt der einfache Weg

update speed m,
    (select 1 as id, 20 as speed union
     select 2 as id, 30 as speed union
     select 99 as id, 10 as speed
        ) t
set m.speed = t.speed where t.id=m.id
Stan Sokolov
quelle
-1

verwenden

REPLACE INTO`table` VALUES (`id`,`col1`,`col2`) VALUES
(1,6,1),(2,2,3),(3,9,5),(4,16,8);

Bitte beachten Sie:

  • id muss ein eindeutiger Primärschlüssel sein
  • Wenn Sie Fremdschlüssel verwenden, um auf die Tabelle zu verweisen, löscht REPLACE und fügt dann ein, sodass dies zu einem Fehler führen kann
Justin Levene
quelle
-3

Im Folgenden werden alle Zeilen in einer Tabelle aktualisiert

Update Table Set
Column1 = 'New Value'

Im nächsten Schritt werden alle Zeilen aktualisiert, in denen der Wert von Spalte 2 mehr als 5 beträgt

Update Table Set
Column1 = 'New Value'
Where
Column2 > 5

Es gibt alle Beispiele von Unkwntech zum Aktualisieren von mehr als einer Tabelle

UPDATE table1, table2 SET
table1.col1 = 'value',
table2.col1 = 'value'
WHERE
table1.col3 = '567'
AND table2.col6='567'
GateKiller
quelle
-3

Ja. Dies ist mit der SQL-Anweisung INSERT ON DUPLICATE KEY UPDATE möglich. Syntax: INSERT INTO Tabellenname (a, b, c) VALUES (1,2,3), (4,5,6) ON DUPLICATE KEY UPDATE a = WERTE (a), b = WERTE (b), c = WERTE (c)

sara191186
quelle
-5
UPDATE tableName SET col1='000' WHERE id='3' OR id='5'

Dies sollte das erreichen, wonach Sie suchen. Fügen Sie einfach weitere IDs hinzu. Ich habe es getestet.

UnkwnTech
quelle
-7
UPDATE `your_table` SET 

`something` = IF(`id`="1","new_value1",`something`), `smth2` = IF(`id`="1", "nv1",`smth2`),
`something` = IF(`id`="2","new_value2",`something`), `smth2` = IF(`id`="2", "nv2",`smth2`),
`something` = IF(`id`="4","new_value3",`something`), `smth2` = IF(`id`="4", "nv3",`smth2`),
`something` = IF(`id`="6","new_value4",`something`), `smth2` = IF(`id`="6", "nv4",`smth2`),
`something` = IF(`id`="3","new_value5",`something`), `smth2` = IF(`id`="3", "nv5",`smth2`),
`something` = IF(`id`="5","new_value6",`something`), `smth2` = IF(`id`="5", "nv6",`smth2`) 

// Du baust es einfach in PHP wie

$q = 'UPDATE `your_table` SET ';

foreach($data as $dat){

  $q .= '

       `something` = IF(`id`="'.$dat->id.'","'.$dat->value.'",`something`), 
       `smth2` = IF(`id`="'.$dat->id.'", "'.$dat->value2.'",`smth2`),';

}

$q = substr($q,0,-1);

So können Sie die Lochtabelle mit einer Abfrage aktualisieren

user2082581
quelle
Ich habe nicht downvote, aber ich denke , die Einwand ist das Set zu tun, wenn es nicht benötigt wird (und man tut es immer noch, wenn Sie setzen somethingauf something)
v010dya