Dummes, aber einfaches Beispiel: Angenommen, ich habe eine Tabelle 'Artikel', in der ich die Gesamtsummen der empfangenen Artikel aufbewahre.
Item_Name Items_In_Stock
Der Artikelname ist hier der Primärschlüssel. Wie erreiche ich Folgendes, wenn ich Artikel A in Menge X erhalte?
Wenn der Artikel nicht vorhanden ist, füge ich einen neuen Wert für Artikel A ein und setze die Artikel auf Lager auf X. Wenn ein Datensatz vorhanden ist, in dem Artikel auf Lager Y waren, lautet der neue Wert für Artikel auf Lager (X + Y).
INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = 27 + (SELECT items_in_stock where item_name = 'A' )
Mein Problem ist, dass ich mehrere Spalten in meiner tatsächlichen Tabelle habe. Ist es eine gute Idee, mehrere select-Anweisungen in den Update-Teil zu schreiben?
Natürlich kann ich das im Code machen, aber gibt es einen besseren Weg?
mysql
performance
upsert
WPFAbsoluteNewBie
quelle
quelle
ON DUPLICATE KEY UPDATE new_items_count = new_items_count + 27
. Da Sie keine anderen Spalten veröffentlicht haben, ist es schwierig, Ihre Frage zu beantworten, da das erwartete Verhalten unbekannt ist. Was machst du mit anderen Spalten? Einige Zahlen aktualisieren oder?new_items_count
hier Ist es eine andere Spalte auf Ihrem Tisch?Antworten:
Wie in meinem Kommentar erwähnt, müssen Sie die Unterauswahl nicht vornehmen, um auf die Zeile zu verweisen, die dazu führt, dass ON DUPLICATE KEY ausgelöst wird. In Ihrem Beispiel können Sie also Folgendes verwenden:
INSERT INTO `item` (`item_name`, items_in_stock) VALUES( 'A', 27) ON DUPLICATE KEY UPDATE `new_items_count` = `new_items_count` + 27
Denken Sie daran, dass die meisten Dinge wirklich einfach sind. Wenn Sie sich dabei ertappen, etwas zu komplizieren, das einfach sein sollte, dann tun Sie es höchstwahrscheinlich falsch :)
quelle
new_items_count = new_items_count + VALUES(items_in_stock)
REPLACE
Abfrage erfolgen? Auf diese Weise ist es viel einfacherAnhand dieses Beispiels können Sie sich ein Bild machen:
Angenommen, Sie möchten benutzerbezogene Daten für sieben Tage hinzufügen
Es sollte einen eindeutigen Wert für Benutzer-ID und Tag haben
Hier ist die Tabelle
CREATE TABLE `table_name` ( `userid` char(4) NOT NULL, `day` char(3) NOT NULL, `open` char(5) NOT NULL, `close` char(5) NOT NULL, UNIQUE KEY `seven_day` (`userid`,`day`) );
Und Ihre Anfrage wird sein
INSERT INTO table_name (userid,day,open,close) VALUES ('val1', 'val2','val3','val4') ON DUPLICATE KEY UPDATE open='val3', close='val4';
Beispiel:
<?php //If your data is $data= array( 'sat'=>array("userid"=>"1001", "open"=>"01.01", "close"=>"11.01"), 'sun'=>array("userid"=>"1001", "open"=>"02.01", "close"=>"22.01"), 'sat'=>array("userid"=>"1001", "open"=>"03.01", "close"=>"33.01"), 'mon'=>array("userid"=>"1002", "open"=>"08.01", "close"=>"08.01"), 'mon'=>array("userid"=>"1002", "open"=>"07.01", "close"=>"07.01") ); //If you query this in a loop //$conn = mysql_connect("localhost","root",""); //mysql_select_db("test", $conn); foreach($data as $day=>$info) { $sql = "INSERT INTO table_name (userid,day,open,close) VALUES ('$info[userid]', '$day','$info[open]','$info[close]') ON DUPLICATE KEY UPDATE open='$info[open]', close='$info[close]'"; mysql_query($sql); } ?>
Ihre Daten werden in der Tabelle aufgeführt:
+--------+-----+-------+-------+ | userid | day | open | close | +--------+-----+-------+-------+ | 1001 | sat | 03.01 | 33.01 | | 1001 | sun | 02.01 | 22.01 | | 1002 | mon | 07.01 | 07.01 | +--------+-----+-------+-------+
quelle
mysql_*
Funktionen verwendet, die in PHP 7 entfernt wurden. Wenn Sie über einen Ersatz nachdenken , sehen Sie sich dieses interessante Rätsel zwischen PDO und MySQLi an.Obwohl Michaels Antwort die richtige ist, müssen Sie ein bisschen mehr wissen, um das Upsert programmgesteuert durchzuführen:
Erstellen Sie zunächst Ihre Tabelle und geben Sie an, für welche Spalten ein eindeutiger Index erstellt werden soll:
CREATE TABLE IF NOT EXISTS Cell ( cellId BIGINT UNSIGNED, attributeId BIGINT UNSIGNED, entityRowId BIGINT UNSIGNED, value DECIMAL(25,5), UNIQUE KEY `id_ce` (`cellId`,`entityRowId`) )
Fügen Sie dann einige Werte ein:
INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
Versuchen Sie dasselbe noch einmal, und Sie erhalten einen doppelten Schlüsselfehler, weil
cellId
undentityRowId
dasselbe sind:INSERT INTO Cell VALUES( 1, 6, 199, 1.0 );
Deshalb verwenden wir den Befehl upsert:
INSERT INTO Cell ( cellId, attributeId, entityRowId, value) VALUES( 1, 6, 199, 300.0 ) ON DUPLICATE KEY UPDATE `value` = `value` + VALUES(`value`)
Dieser Befehl nimmt den
1.0
bereits vorhandenen Wert als Wert und führt a ausvalue = value + 300.0
.Selbst nach Ausführung des obigen Befehls befindet sich nur eine Zeile in der Tabelle, und der Wert ist
301.0
.quelle
301.0
und nicht302.0
?Dies ist die Syntax für einen Upsert
INSERT INTO `{TABLE}` (`{PKCOLUMN}`, `{COLUMN}`) VALUES (:value) ON DUPLICATE KEY UPDATE `{COLUMN}` = :value_dup';
quelle
Wenn Sie Wert für PK - Spalte haben, oder einen eindeutigen Index für eine Spalte , die erfüllt unicity, können Sie verwenden
INSERT IGNORE
,INSERT INTO ... ON DUPLICATE
oderREPLACE
Beispiel mit
INSERT IGNORE
INSERT IGNORE INTO Table1 (ID, serverID, channelID, channelROLE) VALUES (....);
Beispiel mit
INSERT INTO .. ON DUPLICATE KEY UPDATE
SET @id = 1, @serverId = 123545, @channelId = 512580, @channelRole = 'john'; INSERT INTO Table1 (ID, serverID, channelID, channelROLE) VALUES (@id, @serverId, @channelId, @channelRole) ON DUPLICATE KEY UPDATE serverId = @serverId, channelId = @channelId, channelRole = @channelRole;
Beispiel mit
Replace
REPLACE INTO table1 (ID, serverID, channelID, channelROLE) VALUES (...);
quelle
Beispiel für Upsert
INSERT INTO table1 (col1, col2, col3) VALUES ($1, $2, $3) ON CONFLICT (col1) DO UPDATE SET col2 = $2, col3 = $3 WHERE col1 = $1 RETURNING col1
quelle