SQL - UPSERT LOOP通过SELECT的结果集

时间:2018-03-02 03:44:49

标签: tsql sql-server-2016

我有以下查询返回两列数据UserID&来自表格ServiceID的{​​{1}}& a

b

上述查询返回以下数据集:

SELECT a.UserID, b.ServiceID FROM TableA a
JOIN TableB b
ON b.EventID = a.EventID
WHERE a.EventID = 1892286
AND a.Attendance IN (1,2)

我需要以下列方式UPSERT到表UserID ServiceID 1 33 2 44 3 55

如果c&表UserID中存在ServiceID,然后从表c获取列Scheduled的当前值并添加c

如果1&表UserID中不存在ServiceID,然后将记录插入到表c中,并从上面的select语句中选择cUserID,并添加ServiceID进入1列。

我的问题是如何为我的select语句返回的每一行执行此操作,以确保所有结果都已加入表Scheduled

我正在查看循环案例或if-else语句作为可能的解决方案,但感谢任何输入。

我对上述的尝试:

c

3 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是执行不同的语句以进行插入和更新。

{
"name": "BeJson",
"headUrl": "http://www.bejson.com",
"surl": "http://xxx",
"burl": "http://xxx"
}

答案 1 :(得分:1)

如果您使用的是较新版本的SQL Server(此问题标记为sql-server-2016),则可以使用MERGE语句。

以下是基于帖子的简化示例:

--create test tables
CREATE TABLE #a (UserID int);
CREATE TABLE #b (UserID int, ServiceID int);
CREATE TABLE #c (UserID int, ServiceID int, Scheduled int);

--insert some data matching the question
INSERT INTO #a
VALUES(1), (2), (3), (4), (5);

INSERT INTO #b
VALUES (1, 33), (2, 44), (3, 55)

INSERT INTO #c
VALUES(2, 44, 3), (4, 66, 1)

--ensure we have data
SELECT * FROM #a
SELECT * FROM #b
SELECT * FROM #c

--use the MERGE statement
MERGE #c AS tgt
USING(SELECT a.UserID, b.ServiceID FROM #a a JOIN #b b ON a.UserID = b.UserID) src
ON (tgt.UserID = src.UserID AND tgt.ServiceID = src.ServiceID)
WHEN NOT MATCHED THEN
  INSERT (UserID, ServiceID, Scheduled)
  VALUES(src.UserID, src.ServiceID, 1)
WHEN MATCHED THEN
  UPDATE 
    SET Scheduled += 1;

--check what's been inserted/updated
SELECT * FROM #c

请注意,MERGE有时会影响性能,因此请谨慎使用。有关MERGE here

的更多信息

希望这有帮助!

答案 2 :(得分:1)

循环效率不高

cace不是有效的别名,所以我不得不猜测有效的别名

从备份开始,以防你做错了。

update c 
   set c.serviceID = c.serviceID + 1  
  FROM TableA a
  JOIN TableB b
    ON b.EventID = a.EventID
   and a.EventID = 1892286
   AND a.Attendance IN (1,2) 
  join TableC c 
    on c.UserID = a.UserID 
   and c.ServiceID = b.ServiceID; 

INSERT INTO TableC (UserID, ServiceID, Scheduled)
SELECT a.UserID, b.ServiceID, 1 
  FROM TableA a
  JOIN TableB b
    ON b.EventID = a.EventID
   and a.EventID = 1892286
   AND a.Attendance IN (1,2)  
 where not exists (select 1 
                     from TableC c 
                    where c.UserID = a.UserID 
                      and c.ServiceID = b.ServiceID 
                  );