Example of a Simple Merge Statement in SQL Server

The following example uses T-SQL to merge two tables in SQL Server. It uses the VALUES table value constructor as the source table.

Suppose we create a table like this:

CREATE TABLE Idiots (
    IdiotId int IDENTITY(1,1) NOT NULL,
    FirstName varchar(50),
    LastName varchar(50)
    );

INSERT INTO Idiots VALUES 
    ('Peter', 'Griffin'), 
    ('Homer', 'Simpson'), 
    ('Ned', 'Flanders');

SELECT * FROM Idiots;

Result:

+-----------+-------------+------------+
| IdiotId   | FirstName   | LastName   |
|-----------+-------------+------------|
| 1         | Peter       | Griffin    |
| 2         | Homer       | Simpson    |
| 3         | Ned         | Flanders   |
+-----------+-------------+------------+

And suppose we want to perform a merge operation. We want to insert new rows, but if a row already exists with values that match those in our source, then we want to update the existing row instead (instead of inserting a new row).

We can do that like this:

DECLARE @Changes TABLE(Change VARCHAR(20));

MERGE INTO Idiots AS Target  
USING ( VALUES 
            (3, 'Ned', 'Okily Dokily!'), 
            (4, 'Lloyd','Christmas'), 
            (5, 'Harry', 'Dunne')
        ) AS Source ( IdiotId, FirstName, LastName )  
ON Target.IdiotId = Source.IdiotId
AND Target.FirstName = Source.FirstName
WHEN MATCHED THEN
    UPDATE SET FirstName = Source.FirstName, LastName = Source.LastName
WHEN NOT MATCHED BY TARGET THEN
    INSERT (FirstName, LastName) VALUES (Source.FirstName, Source.LastName)
OUTPUT $action INTO @Changes;

SELECT Change, COUNT(*) AS Count  
FROM @Changes  
GROUP BY Change;

Result:

+----------+---------+
| Change   | Count   |
|----------+---------|
| INSERT   | 2       |
| UPDATE   | 1       |
+----------+---------+

Two new rows were inserted and one was updated.

Here, we used a table value constructor (VALUES) to specify the new values for the table.

In this case we checked the IdiotId and FirstName columns. Basically, if the ID and first name are the same, then we want to update the existing row instead of inserting a new one.

We used WHEN MATCHED to specify what should happen when data from our VALUES clause matches data in the target table. In this case, we simply update the row with the new data from VALUES.

We used WHEN NOT MATCHED BY TARGET to specify what should happen when there’s no match. In this case we insert a new row with the new data.

We also used a variable called @Changes to view the output of our merge operation. We used the OUTPUT clause after the merge operation for this. That’s what gave us the resulting table above.

We can now check the target table to see the impact that the merge operation had on it:

SELECT * FROM Idiots;

Result:

+-----------+-------------+---------------+
| IdiotId   | FirstName   | LastName      |
|-----------+-------------+---------------|
| 1         | Peter       | Griffin       |
| 2         | Homer       | Simpson       |
| 3         | Ned         | Okily Dokily! |
| 4         | Lloyd       | Christmas     |
| 5         | Harry       | Dunne         |
+-----------+-------------+---------------+

We can see that Idiot number 3 (Ned) has had his last name updated. We can also see that two new idiots have been added to the table (Lloyd and Harry).