Beginning with MySQL 8.0.19 you can use an alias for that row (see reference).

INSERT INTO beautiful (name, age)
    VALUES
    ('Helen', 24),
    ('Katrina', 21),
    ('Samia', 22),
    ('Hui Ling', 25),
    ('Yumie', 29)
    AS new
ON DUPLICATE KEY UPDATE
    age = new.age
    ...

For earlier versions use the keyword VALUES (see reference, deprecated with MySQL 8.0.20).

INSERT INTO beautiful (name, age)
    VALUES
    ('Helen', 24),
    ('Katrina', 21),
    ('Samia', 22),
    ('Hui Ling', 25),
    ('Yumie', 29)
ON DUPLICATE KEY UPDATE
    age = VALUES(age),
     ...
Answer from Peter Lang on Stack Overflow
🌐
Stack Exchange
dba.stackexchange.com › questions › 258914 › insert-on-duplicate-key-update-to-update-multiple-rows-in-single-query
mysql - INSERT ON DUPLICATE KEY UPDATE to UPDATE multiple rows in single query - Database Administrators Stack Exchange
February 4, 2020 - The id is the primary key and there are no other keys. No UPDATE has to happen if the all of the data for all of the row are the same between the query and table row. Sometimes only one column of data might change, sometimes all columns except id might change.
Discussions

joomla 3.x - with insert on duplicate key update - updating multiple rows at once - Joomla Stack Exchange
With latest joomla version I try to achieve one query to the database and updating multiple rows at once. ... INSERT INTO `tablename` (`id`,`date`) VALUES ('79','2018-12-01'),('78','2018-10-01'),('76','2018-06-01'),('80','2019-01-01') ON DUPLICATE KEY UPDATE (`date` = '2018-12-01'),(`date` ... More on joomla.stackexchange.com
🌐 joomla.stackexchange.com
September 16, 2018
MySQL Insert/Update Multiple Rows Using ON DUPLICATE KEY - Stack Overflow
I'm trying to do an insert that if the id already exists it updates the row instead, but I can't seem to get it to work. This is an abridged version of the insert since there are about 1400 rows... More on stackoverflow.com
🌐 stackoverflow.com
MySQL insert row on duplicate key update multiple columns - Stack Overflow
I have a table (name, date, stat1, stat2, stat3), (name, date) is the PK. When I insert rows, there will be duplicate keys, and I need to sum up the three stats. I use the following query with More on stackoverflow.com
🌐 stackoverflow.com
mysql - INSERT INTO .. ON DUPLICATE KEY UPDATE for multiple items - Stack Overflow
INSERT INTO about_company ( id, ... updatedAt ) VALUES ( 'U74999DL2019PTC3459XZ', '65a9007e09fdf2002810f537', '10000', '2110', 'YO Yo12', 'Private', 'Unlisted', '2023-09-30', '2013-08-05', 'ACTIVE compliant', 'Active', '2024-01-28 01:29:47' ), ( 'U74999DL2019PTC3459XX', '65a9007e09fdf2002810f537', '10000', '22210', 'HoneySingh12', 'Private', 'Unlisted', '2023-09-30', '2013-08-05', 'ACTIVE compliant', 'Active', '2024-01-29 01:29:47' ) ON DUPLICATE KEY UPDATE updatedAt ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
MySQL
dev.mysql.com › doc › refman › 8.0 › en › insert-on-duplicate.html
MySQL :: MySQL 8.0 Reference Manual :: 15.2.7.2 INSERT ... ON DUPLICATE KEY UPDATE Statement
January 13, 2022 - ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.
🌐
Prisma
prisma.io › dataguide › mysql › inserting-and-modifying-data › insert-on-duplicate-key-update
ON DUPLICATE KEY UPDATE to upsert and modify data in MySQL
MySQL considers an ON DUPLICATE KEY UPDATE where an update occurs to the existing row as two rows affected. If no conflict had occurred and the new record had been added, it would instead show one row affected.
🌐
MySQL
dev.mysql.com › doc › en › insert-on-duplicate.html
MySQL :: MySQL 8.4 Reference Manual :: 15.2.7.2 INSERT ... ON DUPLICATE KEY UPDATE Statement
ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.
Top answer
1 of 1
6

Building a REPLACE INTO query is just as simple as building an INSERT ... ON DUPLICATE KEY UPDATE. Note that there is a difference between REPLACE INTO AND ON DUPLICATE KEY UPDATE.

Code:

$columns = ['id', 'date'];
$data = [
    [79, '2018-12-01'],
    [78, '2018-10-01'],
    [76, '2018-06-01'],
    [80, '2019-01-01']
];

$db = JFactory::getDbo();
try {
    foreach ($data as &$row) {
        $row = (int)db->q($row[1]); // flatten 2-dim array and apply security techniques
    }
    $query = $db->getQuery(true)
                ->insert($db->qn('#__tablename'))
                ->columns(columns))
                ->values($data);
    $db->setQuery(substr_replace($query, 'REPLACE', 0, 8));    // swap INSERT for REPLACE
    // in other words: $db->setQuery(str_replace("\r\nINSERT", "REPLACE", $query));
    // or:             $db->setQuery(preg_replace("~^\s+INSERT~", "REPLACE", $query));
    // Joomla puts \r\n at the start of the query; see via var_dump($db) after setQuery()
    /*
    echo "<pre>";
        print_r($db);   // see the updated sql object
    echo "</pre>";
    */
    $db->execute();
} catch (Exception $e) {
    echo  "Syntax Error: " , $e->getMessage();  // never show php's error message to the public
}
echo "<div>" , $db->getAffectedRows() , " row(s) inserted</div>";

This is the query built:

REPLACE INTO `#__tablename`
(`id`,`date`) VALUES 
(79, '2018-12-01'),(78, '2018-10-01'),(76, '2018-06-01'),(80, '2019-01-01')

This will ALWAYS print the same number of affected rows for your batch of four entries:

4 row(s) inserted



As for ON DUPLICATE KEY UPDATE..., this is as simple as appending the clause to the end of the Joomla-generated query and including VALUES() syntax. (only replace the $db->setQuery() line from the above snippet)

$db->setQuery($query . " ON DUPLICATE KEY UPDATE `date` = VALUES(`date`)");

to create this query:

INSERT INTO `#__tablename`
(`id`,`date`) VALUES 
(79, '2018-12-01'),(78, '2018-10-01'),(76, '2018-06-01'),(80, '2019-01-01')
ON DUPLICATE KEY UPDATE `date` = VALUES(`date`)

This type of query behaves differently and gives different feedback in terms of affected rows.

When identical rows exist in the database table for all of the rows that you intend to add, you will see 0 affected rows. If the PRIMARY ID already exists -- let's say 1 row has a different date value than what is in the query -- you will see 2 affected rows (I have run this on my own localhost and despite other things I've read, this must be removing, then adding). So this kind of information can be either very helpful or very confusing depending on what you are trying to determine. Imagine if you have all four ids represented in your table already and two of the four rows need the date value to be updated. After the query executes, you will be notified that 4 rows have been affected.

Here is a relevant answer that I posted a few years ago on StackOverflow.

🌐
MariaDB
mariadb.com › kb › en › insert-on-duplicate-key-update
INSERT ON DUPLICATE KEY UPDATE | Server | MariaDB Documentation
ON DUPLICATE KEY UPDATE (often ... perform an UPDATE. The row/s affected value is reported as 1 if a row is inserted, and 2 if a row is updated, unless the API's CLIENT_FOUND_ROWS flag is set....
🌐
Oracle
docs.oracle.com › cd › E17952_01 › mysql-5.7-en › insert-on-duplicate.html
13.2.5.2 INSERT ... ON DUPLICATE KEY UPDATE Statement
February 9, 2026 - ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.
Find elsewhere
🌐
Plus2Net
plus2net.com › sql_tutorial › sql_update-on-duplicate-key.php
Update multiple records by using ON DUPLICATE KEY UPDATE in MySQL
February 5, 2000 - INSERT INTO `student3` (`id`, `name`, `class`, `social`, `science`, `math`) VALUES (2, 'Max Ruin', 'Three', 86, 57, 86) on duplicate key update social=86,science=57,math=86 We will get a message saying 2 rows inserted, but actually we have updated one record only.
🌐
MySQL Tutorial
mysqltutorial.org › home › mysql basics › mysql insert on duplicate key update statement
MySQL INSERT ON DUPLICATE KEY UPDATE Statement
December 27, 2023 - ON DUPLICATE KEY UPDATE: Specify the action to take if a duplicate key violation occurs. column1 = new_value1, column2=new_value2: Define how existing rows should be updated if a duplicate key is encountered.
🌐
Reddit
reddit.com › r/phphelp › mysql - how can i insert multiple rows with insert on update
r/PHPhelp on Reddit: MySql - How can I insert multiple rows with INSERT ON UPDATE
August 31, 2024 -

Hello,

Been stuck on this one for a while.

Using Mysqli, how can I insert (or update if the key already exists) multiple rows in one transaction?

I would like to loop over this array and execute the query only once, instead of on each iteration of the loop

foreach($challengeData as $challengeId => $status) {



    $this->conn->execute_query('
          INSERT INTO my_table
          (
             challenge_id,
             status
    
          )
          
          VALUES
          (
             ?,?
          )
          
          ON DUPLICATE KEY UPDATE 
             status = VALUES(status)
       ',
       [
          $challengeId,
          $status
       ]
    );



}
Top answer
1 of 2
39

Consider

INSERT INTO table (a,b,c) VALUES (1,2,3)
    -> ON DUPLICATE KEY UPDATE c=c+1;

If a and b are UNIQUE fields, UPDATE occurs on a = 1 OR b = 2. Also when condition a = 1 OR b = 2 is met by two or more entries, update is done only once.

Ex here table table with Id and Name UNIQUE fields

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6

If query is

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7);

then we get

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

which violates uniqueness of Id and Name. Now with

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7;

we get

Id     Name     Value 
1      P        7 
2      C        7 
3      D        29 
4      A        6

Behavior on multiple keys is the following

UPDATE in ON DUPLICATE KEY UPDATE is performed if one of the UNIQUE field equals the value to be inserted. Here, UPDATE is performed on Id = 1 OR Name = C. It is equivalent to

UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C;

What if I want one update only, for either key

Can use UPDATE statement with LIMIT keyword

UPDATE table 
SET Value = 7
WHERE Id = 1 OR Name = C
LIMIT 1;

which will give

Id     Name     Value 
1      P        7 
2      C        3 
3      D        29 
4      A        6

What if I want one update only if values for both keys are matched

One solution is to ALTER TABLE and make the PRIMARY KEY (or uniqueness) work on both fields.

ALTER TABLE table 
DROP PRIMARY KEY,
ADD PRIMARY KEY (Id, Name);

Now, on

INSERT INTO table (Id, Name, Value)
VALUES (1, C, 7)
ON DUPLICATE KEY UPDATE Value = 7;

we get

Id     Name     Value 
1      P        2 
2      C        3 
3      D        29 
4      A        6
1      C        7

since no duplicate (on both keys) is found.

2 of 2
0
  1. how does MySQL behave ... It behaves as expected, that is executes ON DUPLICATE KEY clause.

  2. Can I have one update for either... In reality, you have only one ON DUPLICATE KEY clause, so you need to put some code to differentiate which constraint was involved. Fortunatelly, it is possible. The only thing you should know, the order of assignment matters, and you can assign multiple times. Suppose, you have unique constraint on a and b, and you want to update c only if a uniqueness is involved: ... KEY UPDATE c = IF(a = VALUES(a) and b <> VALUES(b), VALUES(c), c), b = VALUES(b)

    but if you change the order of assignments the second condition within if will be always false.

  3. See 2.

🌐
TutorialsPoint
tutorialspoint.com › mysql › mysql-insert-on-duplicate-update.htm
MySQL − Insert on Duplicate Key Update
When we are trying to insert a new row into a MySQL table column with a UNIQUE INDEX or PRIMARY KEY, MySQL will issue an error, if the value being inserted already exists in the column. This will happen because these constraints require unique values, and duplicate values are not allowed. However, if we use the MySQL ON DUPLICATE KEY UPDATE clause with with the INSERT INTO statement, MySQL will update the existing rows with the new values instead of showing an error.
🌐
Josephscott
blog.josephscott.org › 2011 › 02 › 28 › mysql-insert-on-duplicate-and-multiple-rows
MySQL: INSERT ON DUPLICATE and Multiple Rows – Joseph Scott
Without ON DUPLICATE you’d generally do a SELECT first to see if the value was already in the table, then either do an INSERT or an UPDATE based on the response. What you may not have noticed is that you can combine the multi-row insert and ON DUPLICATE features to do: [sourcecode lang=”sql”] INSERT INTO table_name (a,b,c) VALUES (1,2,3), (4,5,6), (7,8,9) ON DUPLICATE KEY UPDATE c = c + 1; [/sourcecode]
🌐
MySQL
dev.mysql.com › doc › refman › 5.7 › en › insert-on-duplicate.html
MySQL :: MySQL 5.7 Reference Manual :: 13.2.5.2 INSERT ... ON DUPLICATE KEY UPDATE Statement
January 22, 2020 - ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.
🌐
Black Sail Division
blacksaildivision.com › mysql-on-duplicate-key
MySQL insert or update using ON DUPLICATE KEY UPDATE - Black Sail Division
November 22, 2013 - There is also option to make batch insert to database using ON DUPLICATE KEY UPDATE. It will execute update for each given row if there is duplication.