Answers:
克劳德·侯勒(Claude Houle)的回答:应该可以正常工作,并且您还可以具有多个列和其他数据:
INSERT INTO table1 ( column1, column2, someInt, someVarChar )
SELECT table2.column1, table2.column2, 8, 'some string etc.'
FROM table2
WHERE table2.ID = 7;
我只在Access,SQL 2000/2005 / Express,MySQL和PostgreSQL中使用了这种语法,因此应该将它们包括在内。它也应该与SQLite3一起使用。
为了INSERT
从另一个表中获取多值中的一个值,我在SQLite3中执行了以下操作:
INSERT INTO column_1 ( val_1, val_from_other_table )
VALUES('val_1', (SELECT val_2 FROM table_2 WHERE val_2 = something))
我看到的两个答案都特别适合在Informix中使用,并且基本上都是标准SQL。即表示法:
INSERT INTO target_table[(<column-list>)] SELECT ... FROM ...;
与Informix以及所有DBMS配合使用都很好。(从5年前开始,MySQL并不总是支持这种东西;现在,它已经对这种标准SQL语法提供了不错的支持,并且AFAIK可以在这种表示法上正常工作。)列列表是可选的,但按顺序指示目标列,因此SELECT结果的第一列将进入列出的第一列,依此类推。在没有列列表的情况下,SELECT结果的第一列进入目标表的第一列。
系统之间可能会有所不同的是用于标识不同数据库中的表的表示法-该标准对数据库间(更不用说DBMS间)操作了无话可说。使用Informix,可以使用以下表示法来标识表:
[dbase[@server]:][owner.]table
也就是说,您可以指定一个数据库,如果该数据库不在当前服务器中,则可以选择标识托管该数据库的服务器,然后是可选的所有者,点,最后是实际的表名。SQL标准使用术语架构来表示Informix称为所有者。因此,在Informix中,以下任何一种表示法都可以标识一个表:
table
"owner".table
dbase:table
dbase:owner.table
dbase@server:table
dbase@server:owner.table
所有者通常不需要被报价;但是,如果确实使用引号,则需要正确拼写所有者名称-区分大小写。那是:
someone.table
"someone".table
SOMEONE.table
都标识同一张表。使用Informix,使用MODE ANSI数据库会有一个复杂的问题,其中所有者名称通常会转换为大写(informix是例外)。也就是说,在MODE ANSI数据库(不常用)中,您可以编写:
CREATE TABLE someone.table ( ... )
并且系统目录中的所有者名称将为“ SOMEONE”,而不是“ someone”。如果将所有者名称用双引号引起来,则其作用类似于分隔标识符。使用标准SQL,分隔符可以在很多地方使用。使用Informix,您只能在所有者名称周围使用它们-在其他情况下,Informix会将单引号和双引号字符串都视为字符串,而不是将单引号字符串和字符串分开以及将双引号字符串作为分隔标识符。(当然,出于完整性考虑,可以将环境变量DELIMIDENT设置为任何值,但Y最安全-表示双引号始终包围定界标识符,单引号始终包围字符串。)
请注意,MS SQL Server设法使用方括号中包含的[定界标识符]。在我看来,这很奇怪,并且肯定不是SQL标准的一部分。
为了在第一个答案中添加一些内容,当我们只希望从另一个表中获取很少的记录时(在此示例中,仅一个):
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
VALUES (value1, value2,
(SELECT COLUMN_TABLE2
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
使用select子查询插入的两种方法。
1.使用SELECT子查询返回一行结果的方法。
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');
在这种情况下,假设SELECT子查询仅基于WHERE条件或SQL聚合函数(如SUM,MAX,AVG等)返回仅一行结果。否则将引发错误
2.使用SELECT子查询返回多行结果的方法。
INSERT INTO <table_name> (<field1>, <field2>, <field3>)
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;
第二种方法适用于两种情况。
这是另一个将值与select结合使用的示例:
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
当表列顺序已知时,简单插入:
Insert into Table1
values(1,2,...)
简单插入提及列:
Insert into Table1(col2,col4)
values(1,2)
当表(#table2)的选定列数等于插入表(Table1)时的批量插入
Insert into Table1 {Column sequence}
Select * -- column sequence should be same.
from #table2
当您只想插入表(table1)的所需列时进行批量插入:
Insert into Table1 (Column1,Column2 ....Desired Column from Table1)
Select Column1,Column2..desired column from #table2
from #table2
这是另一个使用多个表获取源的示例:
INSERT INTO cesc_pf_stmt_ext_wrk(
PF_EMP_CODE ,
PF_DEPT_CODE ,
PF_SEC_CODE ,
PF_PROL_NO ,
PF_FM_SEQ ,
PF_SEQ_NO ,
PF_SEP_TAG ,
PF_SOURCE)
SELECT
PFl_EMP_CODE ,
PFl_DEPT_CODE ,
PFl_SEC ,
PFl_PROL_NO ,
PF_FM_SEQ ,
PF_SEQ_NO ,
PFl_SEP_TAG ,
PF_SOURCE
FROM cesc_pf_stmt_ext,
cesc_pfl_emp_master
WHERE pfl_sep_tag LIKE '0'
AND pfl_emp_code=pf_emp_code(+);
COMMIT;
这是从多个表插入的方法。此特定示例在多对多场景中都有一个映射表:
insert into StudentCourseMap (StudentId, CourseId)
SELECT Student.Id, Course.Id FROM Student, Course
WHERE Student.Name = 'Paddy Murphy' AND Course.Name = 'Basket weaving for beginners'
(我知道在学生姓名上进行匹配可能返回多个值,但您明白了。当Id是Identity列且未知时,在Id之外进行其他匹配是必要的。)
对于Microsoft SQL Server,我将建议学习解释MSDN上提供的SYNTAX。使用Google,查找语法比以往任何时候都容易。
对于这种特殊情况,请尝试
Google:插入站点:microsoft.com
第一个结果将是http://msdn.microsoft.com/en-us/library/ms174335.aspx
如果发现难以解释页面顶部给出的语法,请向下滚动至示例(“使用SELECT和EXECUTE选项插入其他表中的数据”)。
[ WITH <common_table_expression> [ ,...n ] ]
INSERT
{
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ]
{ <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
}
{
[ ( column_list ) ]
[ <OUTPUT Clause> ]
{ VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n ]
| derived_table <<<<------- Look here ------------------------
| execute_statement <<<<------- Look here ------------------------
| <dml_table_source> <<<<------- Look here ------------------------
| DEFAULT VALUES
}
}
}
[;]
这应该适用于那里可用的任何其他RDBMS。记住所有产品IMO的所有语法是没有意义的。
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;
select *
into tmp
from orders
看起来不错,但是仅当tmp不存在(创建并填充)时才有效。(SQL服务器)
插入现有的tmp表:
set identity_insert tmp on
insert tmp
([OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
,[RequiredDate]
,[ShippedDate]
,[ShipVia]
,[Freight]
,[ShipName]
,[ShipAddress]
,[ShipCity]
,[ShipRegion]
,[ShipPostalCode]
,[ShipCountry] )
select * from orders
set identity_insert tmp off
从任何其他表插入多个记录的最佳方法。
INSERT INTO dbo.Users
( UserID ,
Full_Name ,
Login_Name ,
Password
)
SELECT UserID ,
Full_Name ,
Login_Name ,
Password
FROM Users_Table
(INNER JOIN / LEFT JOIN ...)
(WHERE CONDITION...)
(OTHER CLAUSE)
如果您使用INSERT VALUES路由插入多行,请确保使用括号将VALUES划分为集合,因此:
INSERT INTO `receiving_table`
(id,
first_name,
last_name)
VALUES
(1002,'Charles','Babbage'),
(1003,'George', 'Boole'),
(1001,'Donald','Chamberlin'),
(1004,'Alan','Turing'),
(1005,'My','Widenius');
否则,MySQL对象会出现“列数与第1行的值计数不匹配”的情况,最终当您弄清楚该怎么做时,您将写一篇琐碎的文章。
Postgres接下来支持:创建表company.monitor2作为select * from company.monitor;
如果您想在表中插入一些数据而又不想写列名。
INSERT INTO CUSTOMER_INFO
(SELECT CUSTOMER_NAME,
MOBILE_NO,
ADDRESS
FROM OWNER_INFO cm
WHERE ID>100)
这些表在哪里:
CUSTOMER_INFO || OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS || CUSTOMER_NAME | MOBILE_NO | ADDRESS
--------------|-----------|--------- || --------------|-----------|---------
A | +1 | DC || B | +55 | RR
结果:
CUSTOMER_INFO || OWNER_INFO
----------------------------------------||-------------------------------------
CUSTOMER_NAME | MOBILE_NO | ADDRESS || CUSTOMER_NAME | MOBILE_NO | ADDRESS
--------------|-----------|--------- || --------------|-----------|---------
A | +1 | DC || B | +55 | RR
B | +55 | RR ||