Fork me on GitHub

SQL Server 根据一个表数据修改另外一个表数据

今天在写代码的时候发现一个有趣的问题,同时也暴露了之前写的代码有问题,还好之前没有出现重复的情况,及时发现了这个问题,及时改了回来,不然就GG了

下面先上代码,再给大家解说一下

CREATE TABLE #t1 (id INT,value int)
CREATE TABLE #t2 (id INT,value int)

INSERT #t1(id,value)
VALUES(   1, 1 ),
(   2, 2  ),
(   3, 3  ),
(   4, 4 )

INSERT #t2(id,value)
VALUES(   1, 1 ),
(   1, 2  ),
(   1, 3  )

SELECT * FROM  #t1
SELECT * FROM  #t2

--;
--WITH t1 AS(
--SELECT  b.id,SUM(a.value) value FROM #t2 a INNER JOIN #t1 b ON b.id = a.id GROUP BY b.id)

--UPDATE #t1 SET  #t1.value= a.value+b.value FROM #t1 a INNER JOIN  t1 b ON b.id = a.id  

UPDATE #t1 SET  #t1.value= a.value+t.value FROM #t1 a INNER JOIN  #t2 t ON t.id = a.id


SELECT * FROM #t1


DROP TABLE #t1
DROP TABLE #t2
View Code

 

 其实当你看代码就知道,我想根据b表修改a表,按我们的思维,a表id=1的有一条记录,b表id=1的有三条,

这样级联修改以后应该c结果中id=1的值应该是7才对,但是只有2,说明是a表里面的1加了b表里面的value=1 的第一条记录,我在SQL交流群里面问了一下

有人说a表只有一条记录,b表有三条记录,只匹配了第一条,然后我就试了一下,在a表中造了三条记录

CREATE TABLE #t1 (id INT,value int)
CREATE TABLE #t2 (id INT,value int)

INSERT #t1(id,value)
VALUES(   1, 1 ),
(   1, 2  ),
(   1, 3  ),
(   4, 4 )

INSERT #t2(id,value)
VALUES(   1, 1 ),
(   1, 2  ),
(   1, 3  )

SELECT * FROM  #t1
SELECT * FROM  #t2

--;
--WITH t1 AS(
--SELECT  b.id,SUM(a.value) value FROM #t2 a INNER JOIN #t1 b ON b.id = a.id GROUP BY b.id)

--UPDATE #t1 SET  #t1.value= a.value+b.value FROM #t1 a INNER JOIN  t1 b ON b.id = a.id  

UPDATE #t1 SET  #t1.value= a.value+t.value FROM #t1 a INNER JOIN  #t2 t ON t.id = a.id


SELECT * FROM #t1


DROP TABLE #t1
DROP TABLE #t2
View Code

 

然后出现一件很神奇的事

 

 可以看见,即使a表有三条,匹配的b表依旧只有是第一条

所以及时看见这个坑,阿西吧,又是踩坑的一天,还好检查代码发现了问题

经过修正后的代码,有三种解决方案,第一子查询汇总修改,第二用 CTE(CTE表示公用表表达式,是一个临时命名结果集,始终返回结果集)语法解决,第三种使用循环,

具体使用看实际情况,因为我的级联修改是在循环外,所以就用前两种,我一般使用CTE 语法修改,这个语法用法还是很普遍很爽的,但是使用有限制,脱离主体只能使用一次,

如果你要用多次,建议使用临时表或者表变量(个人推荐表变量,具体使用还是要看情况,差异还是挺大的,有时间我为大家写一篇这三种的异同的随便)

不哔哔,直接上代码

CREATE TABLE #t1 (id INT,value int)
CREATE TABLE #t2 (id INT,value int)

INSERT #t1(id,value)
VALUES(   1, 1 ),
(   2, 2  ),
(   3, 3  ),
(   4, 4 )

INSERT #t2(id,value)
VALUES(   1, 1 ),
(   1, 2  ),
(   1, 3  )

SELECT * FROM  #t1
SELECT * FROM  #t2

--;
--WITH t1 AS(
--SELECT  b.id,SUM(a.value) value FROM #t2 a INNER JOIN #t1 b ON b.id = a.id GROUP BY b.id)

--UPDATE #t1 SET  #t1.value= a.value+b.value FROM #t1 a INNER JOIN  t1 b ON b.id = a.id  

UPDATE #t1 SET  #t1.value= a.value+t.value FROM #t1 a INNER JOIN (SELECT id,SUM(value) value  FROM #t2 WHERE #t2.id=id GROUP BY id)t ON t.id = a.id


SELECT * FROM #t1


DROP TABLE #t1
DROP TABLE #t2
View Code

 

 

 

这就舒服了,终于实现了我要的效果,这是使用子查询的

 

 

这就比较爽了,至于循环就自己下去试一下,可以用游标,也可以用while循环

游标直接修改就行了,用while循环,要先给参考表一个行号,可以用  ROW_NUMBER() 实现

具体看自己,今天分享结束了,想想就后怕,这么大个坑,出问题就GG了,今天分享出来,也希望给大家一个参考

 

posted @ 2022-10-21 15:39  酒笙匿清栀  阅读(1803)  评论(0编辑  收藏  举报