Not really a question, maybe more of a post to see if anyone has comments on this technique. First, a little background. I'm working on a DSS that needs to get data from multiple sources and the project is running on SQL 2008. I wanted to use the new MERGE command, but kept hitting a road block because I need to deactivate entries that don't appear in the data source (NOT MATCHED BY SOURCE), but I can't affect rows from any other source. Maybe it's obvious to some, but aggressive research didn't unearth anything that addressed this scenario. Unsatisfied by the alternatives, I finally found something that works through sure determination, so I wanted to share it as it's a pattern I'm sure others will come across.Here's an example of my problem (consider column [b] to be the Source System Identifier):-- Sample Data Source (1 of 2)declare @t1 table (a int, b int, d int);-- Targetdeclare @t2 table (a int, b int, d int);insert @t1 values (0,1,1),(2,1,1),(5,1,1);insert @t2 values (1,1,0),(2,1,0),(3,1,0),(4,1,0),(1,2,0),(2,2,0);/*a b d----------- ----------- -----------0 1 12 1 15 1 1(3 row(s) affected)a b d----------- ----------- -----------1 1 02 1 03 1 04 1 01 2 02 2 0(6 row(s) affected)--*/MERGE @t2AS TGTUSING @t1AS SRCON TGT.a= SRC.aAND TGT.b= SRC.bWHEN MATCHEDTHEN UPDATESET TGT.d= SRC.dWHEN NOT MATCHED BY TARGETTHEN INSERT (a,b,d)VALUES (SRC.a,SRC.b,SRC.D)WHEN NOT MATCHED BY SOURCETHEN DELETE;select * from @t1;select * from @t2;/*a b d----------- ----------- -----------0 1 12 1 15 1 1(3 row(s) affected)a b d----------- ----------- -----------2 1 15 1 10 1 1(3 row(s) affected)--*/
As expected, we lost data where b = 2 because it didn't match our source. To solve for that, just add a CTE for the target with a WHERE clause restricting the resultset:WITH t2AS(SELECT *FROM @t2 tWHERE EXISTS ( SELECT * FROM @t1 r WHERE r.b = t.b ))MERGE t2AS TGTUSING @t1AS SRCON TGT.a= SRC.aAND TGT.b= SRC.bWHEN MATCHEDTHEN UPDATESET TGT.d= SRC.dWHEN NOT MATCHED BY TARGETTHEN INSERT (a,b,d)VALUES (SRC.a,SRC.b,SRC.D)WHEN NOT MATCHED BY SOURCETHEN DELETE;select * from @t1;select * from @t2;/*a b d----------- ----------- -----------0 1 12 1 15 1 1(3 row(s) affected)a b d----------- ----------- -----------2 1 11 2 02 2 05 1 10 1 1(5 row(s) affected)--*/
Now, we can MERGE multiple data sources into a consolidated target effectively. WOOT!