MERGE声明问题

时间:2016-10-15 07:16:10

标签: sql sql-server sql-server-2012

我有一个包含三列的表[ExistingTable]IDValueDate

+----+------------------+
| ID | Value | Date     |
+----+------------------+
| 1  | 100   |2016-01-01|
| 1  | 200   |2016-01-01|
| 1  | 300   |2016-01-01|
| 2  | 200   |2016-01-01|
| 2  | 300   |2016-01-01|
+----+------------------+

和第二个表[NewTable]

+----+------------+
| ID | Value      |
+----+------------+
| 1  | 100        |
| 1  | 200        |
| 1  | 400        |
| 2  | 200        |
| 2  | 300        |
+----+------------+

如果我写一个合并语句,如:

MERGE [ExistingTable] AS T1
USING [NewTable] AS T2 ON (T1.[ID] = T2.[ID] AND T1.[Value] = T2.[Value])

WHEN NOT MATCHED THEN 
    INSERT([ID], [Value], [Date]) 
    VALUES(T2.[ID], T2.[Value], Getdate())

WHEN MATCHED THEN 
    UPDATE SET [Date] = Getdate();

查询将插入ID = 1 AND Value = 400,它将更新所有其余数据的日期。

但是,我想为所有INSERT字段值设置ID,这个字段值尚未匹配,在此示例中,我希望获得此类结果:

+----+------------------+
| ID | Value | Date     |
+----+------------------+
| 1  | 100   |2016-01-01|
| 1  | 200   |2016-01-01|
| 1  | 300   |2016-01-01|
| 2  | 200   |2016-10-15|
| 2  | 300   |2016-10-15|
| 1  | 100   |2016-10-15|
| 1  | 200   |2016-10-15|
| 1  | 400   |2016-10-15|
+----+------------------+

使用 MERGE 声明是否可以实现?

1 个答案:

答案 0 :(得分:0)

我认为这可以通过CTE和INSERT完成:

;WITH cte AS ( --here we will store all ID's that have 1 and more not matched Values
SELECT n.ID
FROM [NewTable] n
LEFT JOIN ExistingTable e
    ON n.ID = e.id and n.[Value] = e.[Value]
WHERE e.ID IS NULL
)

INSERT INTO ExistingTable
SELECT  n.ID,
        n.[Value],
        GETDATE()
FROM [NewTable] n
INNER JOIN cte c
    ON c.ID = n.ID

如果您从ExistingTable中选择,您将获得:

ID  Value   Date
1   100     2016-01-01
1   200     2016-01-01
1   300     2016-01-01
2   200     2016-01-01
2   300     2016-01-01
1   100     2016-10-15
1   200     2016-10-15
1   400     2016-10-15