SQL Server多表关联去重数据批量插入的单脚本实现需求
一步实现多企业证书数据去重插入
我来帮你解决这个重复操作的麻烦!你之前分步处理每个企业的方式,在企业数量多、数据量大的时候确实效率很低,咱们可以通过表关联+去重的方式,用单条SQL语句直接完成所有数据的插入,不用反复执行插入和更新。
先说说你之前尝试的脚本问题
你写的嵌套子查询有几个明显问题:
(select distinct certno)没有指定来源表,SQL执行时会直接报错- 内层的
select companyid from Table2 where company in (select company from Table1)会返回多个companyid值,无法匹配单条记录,执行时会触发“子查询返回的值不止一个”的错误
正确的单脚本实现方案
根据你的需求,我们可以通过JOIN关联Table1和Table2,再用DISTINCT或者GROUP BY实现按certno去重,一步插入所有符合要求的数据:
方案1:用DISTINCT去重(适合同certno对应唯一expdate/company的场景)
这是最直接的方式,因为你的示例数据里同一个certno对应的expdate和company都是一致的,DISTINCT会自动过滤掉重复的certno记录:
INSERT INTO Table3 (companyid, certno, expdate, createddate, is_null) SELECT DISTINCT t2.companyid, t1.certno, t1.expdate, GETDATE(), -- 自动获取当前时间作为createddate 1 -- 直接设置is_null为1,无需后续更新 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.company = t2.company; -- 通过company字段关联两张表
方案2:用GROUP BY去重(更严谨,适合可能存在同certno不同expdate的场景)
如果担心未来数据里出现同一个certno对应不同expdate的情况,可以用GROUP BY强制按certno分组,同时指定取哪一个expdate(比如最新/最早的):
INSERT INTO Table3 (companyid, certno, expdate, createddate, is_null) SELECT t2.companyid, t1.certno, MAX(t1.expdate), -- 取该certno对应的最新过期日期,也可以用MIN取最早的 GETDATE(), 1 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.company = t2.company GROUP BY t2.companyid, t1.certno; -- 按公司ID和证书编号分组,确保每个certno只出现一次
安全提示
执行插入前,建议先去掉INSERT INTO部分,用SELECT语句预览结果,确认数据符合预期后再执行插入,避免误操作:
-- 先预览数据,确认无误再执行插入 SELECT DISTINCT t2.companyid, t1.certno, t1.expdate, GETDATE() AS createddate, 1 AS is_null FROM Table1 t1 INNER JOIN Table2 t2 ON t1.company = t2.company;
内容的提问来源于stack exchange,提问作者Nadhirah21
相关产品推荐
相关产品推荐

