插入…值(SELECT … FROM …)

我试图插入到一个表使用来自另一个表的input。 尽pipe对于许多数据库引擎来说这是完全可行的,但是我总是很难记住当天SQL引擎( MySQL , Oracle , SQL Server , Informix和DB2 )的正确语法。

是否有一个来自SQL标准(例如, SQL-92 )的silver-bullet语法,允许我插入值而不用担心底层数据库?

尝试:

INSERT INTO table1 ( column1 ) SELECT col1 FROM table2 

这是标准的ANSI SQL,可以在任何DBMS上工作

它绝对适用于:

  • 神谕
  • MS SQL Server
  • MySQL的
  • Postgres的
  • SQLite v3
  • Teradata数据
  • DB2
  • SYBASE
  • Vertica的
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA

@ Shadow_x99 :应该可以正常工作,而且还可以有多个列和其他数据:

 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的结果的第一列进入目标表的第一列。

系统之间有什么不同之处在于用于标识不同数据库中的表的标记 – 标准对于数据库间(更不用说数据库间pipe理系统)操作没有什么可说的。 使用Informix,可以使用以下表示法来标识表:

 [dbase[@server]:][owner.]table 

也就是说,您可以指定一个数据库,如果它不在当前服务器中,则可以select标识承载该数据库的服务器,然后指定一个可选的所有者,点,最后是实际的表名称。 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 ( ... ) 

而系统目录中的所有者名称将是“某人”,而不是“某人”。 如果您将所有者名称用双引号括起来,它就像分隔的标识符一样。 使用标准的SQL,分隔标识符可以在很多地方使用。 对于Informix,只能在所有者名称周围使用它们 – 在其他上下文中,Informix将单引号和双引号string视为string,而不是将单引号string作为string和双引号string分隔为分隔标识符。 (当然,为了完整起见,还有一个环境variablesDELIMIDENT,可以设置为任意值,但是Y是最安全的 – 表示双引号总是围绕分隔标识符,单引号总是围绕string。

请注意,MS SQL Server设法使用方括号中的[分隔标识符]。 它看起来很奇怪,当然不是SQL标准的一部分。

大多数数据库遵循基本的语法,

 INSERT INTO TABLE_NAME SELECT COL1, COL2 ... FROM TABLE_YOU_NEED_TO_TAKE_FROM ; 

我使用的每个数据库都遵循这个语法,即DB2SQL ServerMY SQLPostgresQL

如果您要为SELECT部分中的所有列提供值,则可以在不指定INSERT INTO部分中的列的情况下完成此操作。

比方说,table1有两列。 这个查询应该工作:

 INSERT INTO table1 SELECT col1, col2 FROM table2 

这不会工作( col2值没有指定):

 INSERT INTO table1 SELECT col1 FROM table2 

我正在使用MS SQL Server。 我不知道其他RDMS是如何工作的。

在第一个答案中添加一些东西,当我们只需要从另一个表(这个例子中只有一个)的几个logging:

 INSERT INTO TABLE1 (COLUMN1, COLUMN2, COLUMN3, COLUMN4) VALUES (value1, value2, (SELECT COLUMN_TABLE2 FROM TABLE2 WHERE COLUMN_TABLE2 like "blabla"), value4); 

表列序列已知时简单插入:

  Insert into Table1 values(1,2,...) 

简单的插入提栏:

  Insert into Table1(col2,col4) values(1,2) 

当表(#table2)的选定列数等于插入表(表1)时批量插入

  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 

这是使用select使用值的另一个示例:

 INSERT INTO table1(desc, id, email) SELECT "Hello World", 3, email FROM table2 WHERE ... 

这是如何从多个表插入。 这个特殊的例子是你在许多情况下有一个映射表的地方:

 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以外的内容是不必要的。)

 INSERT INTO yourtable SELECT fielda, fieldb, fieldc FROM donortable; 

这适用于所有DBMS

如果要使用SELECT * INTO表插入所有列,则可以尝试此操作。

 SELECT * INTO Table2 FROM Table1; 

对于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查询的VALUES部分,只是使用SELECT查询如下。

 INSERT INTO table1 ( column1 , 2, 3... ) SELECT col1, 2, 3... FROM table2 

我其实更喜欢SQL Server 2008中的以下内容:

 SELECT Table1.Column1, Table1.Column2, Table2.Column1, Table2.Column2, 'Some String' AS SomeString, 8 AS SomeInt INTO Table3 FROM Table1 INNER JOIN Table2 ON Table1.Column1 = Table2.Column3 

它消除了添加Insert()集的步骤,并且您只需select表中的哪些值。

这里是另一个使用多个表格来源的例子:

 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 table1 select * from table2 

这个句子和Oracle的有些不同。

 select * into tmp from orders 

看起来不错,但只有在tmp不存在的情况下才能使用(创build并填充)。 (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 VALUESpath来插入多行,请确保使用圆括号将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行的值计数”,你最终写了一个微不足道的职位,当你终于弄清楚如何处理它。

  • INSERT INTO SELECT语句从一个表中复制数据并将其插入到另一个表中。

  • INSERT INTO SELECT要求源表和目标表中的数据types匹配目标表中的现有logging不受影响

INSERT INTO SELECT语法: –

 INSERT INTO table2 SELECT * FROM table1 WHERE condition; 

INSERT INTO SELECT示例: –

 INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) SELECT SupplierName, ContactName, Address, City, PostalCode, Country FROM Suppliers;