Merge (SQL)

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by ClueBot NG (talk | contribs) at 10:13, 13 November 2013 (Reverting possible vandalism by 110.172.168.13 to version by Chuunen Baka. False positive? Report it. Thanks, ClueBot NG. (1583930) (Bot)). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

A relational database management system uses SQL MERGE (also called upsert) statements to INSERT new records or UPDATE existing records depending on whether or not a condition matches. It was officially introduced in the SQL:2003 standard, and expanded in the SQL:2008 standard.

Usage

 MERGE INTO tablename USING table_reference ON (condition)
   WHEN MATCHED THEN
   UPDATE SET column1 = value1 [, column2 = value2 ...]
   WHEN NOT MATCHED THEN
   INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...

Right join is employed over the Target (the INTO table) and the Source (the USING table / view / sub-query). That is:

  • If rows present in the Source but missing from the Target do run the action then specifically the NOT MATCHED action
  • If rows missing from the Source and present in Target are ignored then no action is performed on the Target.

If multiple Source rows match a given Target row, an error is mandated by SQL:2003 standards. You cannot update a Target row multiple times with a MERGE statement

Implementations

Database management systems Oracle Database, DB2, Teradata, EXASOL and MS SQL support the standard syntax. Some also add non-standard SQL extensions.

Synonymous

Some database implementations adopted the term "Upsert" (a portmanteau of update and insert) to a database statement, or combination of statements, that inserts a record to a table in a database if the record does not exist or, if the record already exists, updates the existing record. It is also used to abbreviate the "MERGE" equivalent pseudo-code.

It is used in Microsoft SQL Azure and MongoDB.

MongoDB provides an atomic upsert operation, which creates a new document by combining the criteria for the update with the fields to change.

Example

Suppose a collection is used to track the number of times each page of a website is viewed. Upserts can be used to avoid "seeding" the collection with all possible pages in advance. The collection starts off empty:

 > db.pages.find()

On each page view, the page's document is created if it doesn't exist yet and its views are incremented if it does.

 > db.pages.update({"_id" : "http://www.example.com"}, {"$inc" : {"views" : 1}}, {upsert : true})
 > db.pages.find()
 { "_id" : "http://www.example.com", "views" : 1 }
 > db.pages.update({"_id" : "http://www.example.com"}, {"$inc" : {"views" : 1}}, {upsert : true})
 { "_id" : "http://www.example.com", "views" : 2 }

Other non-standard implementations

Some other database management systems support this, or very similar behavior, through their own, non-standard SQL extensions.

MySQL, for example, supports the use of INSERT ... ON DUPLICATE KEY UPDATE syntax[1] which can be used to achieve a similar effect with the limitation that the join between target and source has to be made only on PRIMARY KEY or UNIQUE constraints, which is not required in the ANSI/ISO standard. It also supports REPLACE INTO syntax,[2] which first attempts an insert, and if that fails, deletes the row, if exists, and then inserts the new one. There is also an IGNORE clause for the INSERT statement,[3] which tells the server to ignore "duplicate key" errors and go on (existing rows will not be inserted or updated, but all new rows will be inserted).

SQLite's INSERT OR REPLACE INTO works similarly. It also supports REPLACE INTO as an alias for compatibility with MySQL.[4]

Firebird supports MERGE INTO though fails at throwing error when multiple Source data. Additionally a single-row version, UPDATE OR INSERT INTO tablename (columns) VALUES (values) [MATCHING (columns)], but the latter does not give you the option to take different actions on insert vs. update (e.g. setting a new sequence value only for new rows, not for existing ones.)

IBM DB2 extends syntax with multiple WHEN MATCHED and WHEN NOT MATCHED clauses, distinguishing them with ... AND some-condition guards.

Microsoft SQL extends with supporting guards and also with supporting Left Join via WHEN NOT MATCHED BY SOURCE clauses.

See also

References

  1. ^ MySQL :: MySQL 5.1 Reference Manual :: 12.2.4.3 INSERT ... ON DUPLICATE KEY UPDATE Syntax
  2. ^ MySQL 5.1 Reference Manual: 11.2.6 REPLACE Syntax
  3. ^ "MySQL 5.5 Reference Manual :: 13.2.5 INSERT Syntax". Retrieved 29 October 2013.
  4. ^ "SQL As Understood By SQLite: INSERT". Retrieved 2012-09-27.

External links