Reputation: 3427
I want to copy rows from Table2 into Table1 as long as they don't already exist in Table1. Right now I get the generic errors Incorrect syntax near the keyword 'WHERE'.
and Incorrect syntax near the keyword 'NOT'.
DECLARE @UserID varchar(100)
SET @UserID = 'me'
INSERT INTO Table1 (Col1, Col2, Col3, Col4, Col7,
Col8, Col9, Col5, Col6)
(SELECT 2 AS [Col1], Col2, Col3, Col4, Col7,
Col8s, GETDATE() AS [Col9], @UserID AS [Col5], GETDATE() AS [Col6]
FROM Table2 AS bpt)
WHERE (SELECT (CONVERT(varchar(10), Col2) + Col3 + Col4) FROM Table2) NOT EXISTS
(SELECT (CONVERT(varchar(10), Col2) + Col3 + Col4) FROM Table1)
Upvotes: 0
Views: 53
Reputation: 3756
Using your original query as the base, here are both the LEFT JOIN and IF NOT EXISTS versions of the query:
DECLARE @UserID varchar(100)
SET @UserID = 'me'
INSERT INTO Table1 (
Col1, Col2, Col3, Col4,
Col7, Col8, Col9, Col5,
Col6)
SELECT 2 AS [Col1],
Col2, Col3, Col4, Col7,
Col8s, GETDATE() AS [Col9],
@UserID AS [Col5],
GETDATE() AS [Col6]
FROM Table2 AS bpt
LEFT JOIN Table1 as exc
ON bpt.Col2 = exc.Col2
AND bpt.Col3 = exc.Col3
AND bpt.Col4 = exc.Col4
WHERE bpt.Col2 IS NULL
-- Alternate version using EXISTS:
DECLARE @UserID varchar(100)
SET @UserID = 'me'
INSERT INTO Table1 (
Col1, Col2, Col3, Col4,
Col7, Col8, Col9, Col5,
Col6)
SELECT 2 AS [Col1],
Col2, Col3, Col4, Col7,
Col8s, GETDATE() AS [Col9],
@UserID AS [Col5],
GETDATE() AS [Col6]
FROM Table2 AS bpt
WHERE NOT EXISTS (
SELECT *
FROM Table1
WHERE bpt.Col2 = exc.Col2
AND bpt.Col3 = exc.Col3
AND bpt.Col4 = exc.Col4
)
I don't recommend the MERGE version for inserting if the row does not exist solely because MERGE is slower than either of these options.
Upvotes: 0
Reputation: 20494
Sometimes I prefer the organization of a MERGE
statement over an INSERT
, even though if all you do is insert with the MERGE
then they are effectively the same thing.
In your case it allows you can compare each key as you would naturally do in a join, instead of concatenating strings to make a massive key.
MERGE table1 AS tgt
USING (
SELECT 2 AS [Col1], Col2, Col3, Col4, Col7,
Col8, GETDATE() AS [Col9], @UserID AS [Col5], GETDATE() AS [Col6]
FROM Table2
) AS src
ON src.Col2 = tgt2.Col2 AND src.Col3 = tgt.Col3 AND src.Col4 = tgt.Col4
WHEN NOT MATCHED THEN
INSERT (Col1, Col2, Col3, Col4, Col5, Col6, Col7, Col8, Col9)
VALUES (src.Col1, src.Col2, src.Col3, src.Col4, src.Col5, src.Col6, src.Col7, src.Col8, src.Col9)
Here's an alternative method where you left join to the table and keep all that don't match. It'll work but I feel the logic on the merge is more straight forward.
INSERT INTO table1 (Col1, Col2, /* ... */ Col9)
SELECT src.Col1, src.Col2, /* ... */ Col9)
FROM (
SELECT 2 AS [Col1], Col2, Col3, Col4, Col7,
Col8, GETDATE() AS [Col9], @UserID AS [Col5], GETDATE() AS [Col6]
FROM Table2
) src
LEFT JOIN table1 tgt ON tgt.Col2 = src.Col2 AND tgt2.Col3 = src.Col3 AND tgt.Col4 = src.Col4
WHERE tgt.[PrimaryKey] IS NULL -- keep rows where there was no match to table1
Upvotes: 0
Reputation: 590
If you don't have primary keys to match on , try something like this
INSERT Table1 (col1,col2)
SELECT col1,col2 from
(
SELECT col1,col2 FROM table2
EXCEPT
SELECT col1, col2 FROM TABLE1
) A
Upvotes: 0
Reputation: 175
You can use below query to create the select statement for insertion in table 1.
SELECT col1,col2
FROM table2
WHERE NOT EXISTS (SELECT col1,col2
FROM table1
WHERE table1.pk = table2.pk);
PK ----> Primary key
Upvotes: 2