问题:在实际的系统开发和后期的数据维护工作中,经常会遇到这样的需求—将一个表的增量数据插入到该数据表中。
这个需求场景可以这么理解:
第一种、A系统和B系统共用某一基础数据,但A系统是在内网部署,为了严格的安全考虑,只允许B系统定期去A系统所在内网,现场将该基础数据导出为excel表(或者导出为insert into语句),再通过光盘拷贝。B系统就需要将excel表数据导入到自己系统的数据库。
第二种、C系统的某个基础数据,需要由专门人员定期统计,然后维护到数据库中。
实际业务中,我遇到的情况是第一种,但是我准备用第二种情况举例子,效果是一样的。(我们的目的是搞清楚怎么实现这个需求,不必去追求鸡蛋到底是哪只母鸡下的。)
我们就假定有个学生信息管理系统,学生表student的数据,由辅导员在新生开学前将新生的数据从excel导入到student表中,而这个excel表也包括了以往已经导入的学生信息。此时要解决的问题就是,如何只是将这一届新生的数据导入,而不是导入全部的数据。
下图是辅导员整理的学生数据excel表,其中绿色背景的为新一届学生信息,白色的是去年的学生信息。
学生信息管理系统的学生表结构:
学生表中原有数据:
现在我们来解决这个问题。
第一步、复制student表结构生成一张临时表:
CREATE TABLE student_tmp SELECT * FROM student WHERE 1=2;
第二步、将excel表数据导入到临时表student_tmp中。成功后,此时student_tmp表数据如下:
第三步、就需要使用left join语句。我们先来看left join不设置where条件,且显示所有表信息的查询结果。
现在我们知道了查询结果列表右下角为null的那些数据,就是我们这次需要同步到student表中的数据。
速度修改查询语句。
SELECT f.* FROM student_tmp f LEFT JOIN student r ON f.id = r.id WHERE r.id IS NULL;
如图,这正是我们想要的结果:
所以最终我们的sql为:
INSERT INTO student SELECT
f.*
FROM
student_tmp f
LEFT JOIN student r ON f.id = r.id
WHERE
r.id IS NULL;
执行结果ok:
[SQL]INSERT INTO student SELECT
f.*
FROM
student_tmp f
LEFT JOIN student r ON f.id = r.id
WHERE
r.id IS NULL;
受影响的行: 5
时间: 0.125s
此时student表的数据:
如上图,学生信息的增量数据已经成功地insert into到了student表中,打完,收工。
编者按:本文由弄青春原创,如果您喜欢,劳驾您点个赞,也欢迎您留下宝贵的评论!若要转载,请注明出处!