1. 语法介绍
有三张表a、b、c,现在需要从表b和表c中分别查几个字段的值插入到表a中对应的字段。对于这种情况,可以使用如下的语句来实现:
INSERT INTO db1_name (field1,field2) SELECT field1,field2 FROM db2_name
上面的语句比较适合两个表的数据互插,如果多个表就不适应了。对于多个表,可以先将需要查询的字段JOIN起来,然后组成一个视图后再SELECT FROM就可以了:
INSERT INTO a (field1,field2) SELECT * FROM(SELECT b.f1,c.f2 FROM b JOIN c) AS tb
其中f1是表b的字段,f2是表c的字段,通过JOIN查询就将分别来自表b和表c的字段进行了组合,然后再通过SELECT嵌套查询插入到表a中,这样就满足了这个场景了,如果需要不止2个表,那么可以多个JOIN的形式来组合字段。
2. 语法错误注意
需要注意的是嵌套查询部分最后一定要有设置表别名,如下:
SELECT * FROM (SELECT f1,f2 FROM b JOIN c) AS tb
即最后的AS tb是必须的(tb这个名称可以随意取),即指定一个别名。每个派生出来的新表都必须指定别名,否则在mysql中会报如下错误:
ERROR 1248 (42000): Every derived TABLE must have its own alias
另外,MySQL中INSERT INTO SELECT不能加VALUES,即不能写成如下形式:
INSERT INTO db1_name(field1,field2) VALUES SELECT field1,field2 FROM db2_name
否则也会报错:You have an error in your SQL syntax
2. 实例演示一
> INSERT INTO zodiac.uc_app_grant(VISITER_ID,VISITER_TYPE,RESOURCE_ID,GMT_GRANT) SELECT ID,'USER','4',NOW() FROM zodiac.uc_user;
3. MYSQL INSERT INTO SELECT不插入重复的数据
MYSQL 判断指定的记录值是否存在,再执行是否插入数据的写法:此语句是插入指定的值,并且判断这些值是否存在于表中,并非复制表的数据:
INSERT INTO TABLE_NAME SELECT ?(想插入的数据,可若干个, 与表的字段对应)
FROM DUAL(MYSQL的虚拟表) WHERE ?(想插入的数据,可若干个,与后面的SELECT对应)
NOT IN (SELECT ?(想不重复的字段,可若干个) FROM TABLE_NAME)
例子:
表 t_test:ID, Name, Value 三个字段
+----+----------+-------+
| ID | Name | Value |
+----+----------+-------+
| 1 | testName | 1 |
+----+----------+-------+
已有上面数据记录,
我们若插入重复的数据,则该语句会判断后再执行插入操作:
INSERT INTO t_test(Name, Value) SELECT 'testName', 'testValue' FROM DUAL WHERE 'testName' NOT IN (SELECT Name FROM t_test);
上面语句表示:当testName不存在t_test表中name字段时,则插入testName, testValue于表中
执行后:
Query OK, 0 rows affected
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from t_test;
+----+----------+-------+
| ID | Name | Value |
+----+----------+-------+
| 1 | testName | 1 |
+----+----------+-------+
1 row in set
因为testName存在于t_test表中,数据重复,则没写进表中。
该语句也可以直接在JDBC中使用,测试OK!
4. 实例演示二
>
INSERT INTO zodiac.uc_app_grant(VISITER_ID,VISITER_TYPE,RESOURCE_ID,GMT_GRANT)
SELECT ID,'USER','4',NOW() FROM zodiac.uc_user WHERE ID IS NOT NULL;