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

其实当你看代码就知道,我想根据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

然后出现一件很神奇的事

可以看见,即使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

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

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

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

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

SQL Server 根据一个表数据修改另外一个表数据的更多相关文章

  1. Sql Server 中将由逗号“,”分割的一个字符串转换为一个表集,并应用到 in 条件中

    Sql Server 中将由逗号“,”分割的一个字符串,转换为一个表,并应用与 in 条件 ,,) 这样的语句和常用,但是如果in 后面的 1,2,3是变量怎么办呢,一般会用字符串连接的方式构造sql ...

  2. SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)

    1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地 ...

  3. 在SQL Server 2008 Management Studio中修改表字段顺序

    有时我们可能需要为一个已存在的数据库表添加字段,并且想让这个字段默认排的靠前一些,这时就需要为表字段重新进行排序,默认情况下在Management Studio中调整顺序并保存时会提示"不允 ...

  4. 在SQL Server 2018 Management Studio中修改表字段顺序

    有时我们可能需要为一个已存在的数据库表添加字段,并且想让这个字段默认排的靠前一些,这时就需要为表字段重新进行排序,默认情况下在Management Studio中调整顺序并保存时会提示“不允许保存更改 ...

  5. SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database)

    原文:SQL Server 游标运用:查看所有数据库所有表大小信息(Sizes of All Tables in All Database) 一.本文所涉及的内容(Contents) 本文所涉及的内容 ...

  6. SQL Server 2008 安装过程中遇到“性能计数器注册表配置单元一致性”检查失败 问题的解决方法

    操作步骤: 1. 在 Microsoft Windows 2003 或 Windows XP 桌面上,依次单击"开始"."运行",然后在"打开&quo ...

  7. SQL Server— 存在检测、建库、 建表、约束、外键、级联删除

    /******************************************************************************** *主题: SQL Server- 存 ...

  8. SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)

    原文:[转]SQL SERVER 2005中如何获取日期(一个月的最后一日.上个月第一天.最后一天.一年的第一日等等) 在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天       ...

  9. sql server 使用链接服务器连接Oracle,openquery查询数据

      对接问题描述:不知道正式库oracle数据库账户密码,对方愿意在对方的客户端上输入账号和密码,但不告诉我们 解决方案:使用一台sql server作为中间服务器,可以通过转存数据到sql serv ...

  10. 在sql server中建存储过程,如果需要参数是一个可变集合怎么处理?

    在sql server中建存储过程,如果需要参数是一个可变集合的处理 原存储过程,@objectIds 为可变参数,比如 110,98,99 ALTER PROC [dbo].[Proc_totalS ...

随机推荐

  1. LeeCode链表问题(二)

    LeeCode 19: 删除链表的倒数第n个节点 题目描述: 给你一个链表,删除链表的倒数第 n 个节点,并返回链表的头节点. 标签:链表,双指针 时间复杂度:O(N) 建立模型: 定义虚拟头节点,使 ...

  2. ILLA Cloud: 调用 Hugging Face Inference Endpoints,开启大模型世界之门

    一个月前,我们 宣布了与 ILLA Cloud 与达成的合作,ILLA Cloud 正式支持集成 Hugging Face Hub 上的 AI 模型库和其他相关功能. 今天,我们为大家带来 ILLA ...

  3. 介绍ServiceSelf项目

    ServiceSelf 做过服务进程功能的同学应该接触过Topshelf这个项目,它在.netframework年代神一搬的存在,我也特别喜欢它.遗憾的是在.netcore时代,这个项目对.netco ...

  4. abp(net core)+easyui+efcore实现仓储管理系统——模块管理升级之上(六十一)

    Abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...

  5. AI测试101:测试AI系统的实用技巧&ML和AI自动化工具

    基于人工智能的系统,也称为神经网络(NN Neural Networks),和其他应用程序一样是 "系统",因此需要测试.本文将指导你测试AI和基于NN的系统,并理解相关概念. 测 ...

  6. 【LeetCode动态规划#10】完全背包问题实战,其三(单词拆分,涉及集合处理字符串)

    单词拆分 力扣题目链接(opens new window) 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词. 说明: 拆 ...

  7. redission分布式redis锁使用

    public void lock(String key, List<Long> idx) { if (CollectionUtils.isEmpty(idx)) { return; } i ...

  8. elastic-job源码(1)- job自动装配

    版本:3.1.0-SNAPSHOT git地址:https://github.com/apache/shardingsphere-elasticjob   Maven 坐标 <dependenc ...

  9. Linux tinyhttpd编译总结

    编译环境:ubuntu16.04  x64 直接make编译tinyhttpd弹出如下错误和打印信息 其中报出两个错误信息,一个是cannot find -lsocket,另外一个就是pthread_ ...

  10. Valgrind交叉编译

    Valgrind交叉编译 编译环境:ubuntu16.04 x64 开发平台:hisi3535 arm板 1.下载Valgrind 我下载的版本为 valgrind-3.12.0.tar.bz2 所有 ...