插入到…值(选择…从…)

我正在尝试使用来自另一个表的输入INSERT INTO表。尽管这对许多数据库引擎来说是完全可行的,但我似乎总是很难记住当天排名第一的引擎(mysqlOracleSQL服务器InformixDB2)的正确语法。

是否有来自SQL标准(例如,SQL-92)的灵丹妙药语法,允许我插入值而不必担心底层数据库?

3132541 次浏览

尝试:

INSERT INTO table1 ( column1 )SELECT  col1FROM    table2

这是标准的ANSISQL,应该适用于任何DBMS

它肯定适用于:

  • Oracle
  • MSSQL服务器
  • mysql
  • Postgres
  • SQLite v3
  • Teradata
  • DB2
  • 赛贝斯
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
  • google spanner

Claude Houle的回答:应该可以正常工作,你也可以有多个列和其他数据:

INSERT INTO table1 ( column1, column2, someInt, someVarChar )SELECT  table2.column1, table2.column2, 8, 'some string etc.'FROM    table2WHERE   table2.ID = 7;

我只在Access、SQL2000/2005/Express、MySQL和PostgreSQL中使用过这种语法,所以应该涵盖这些。它也应该适用于SQLite3。

我看到的两个答案在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".tabledbase:tabledbase:owner.tabledbase@server:tabledbase@server:owner.table

所有者一般不需要引用;但是,如果您确实使用引号,则需要正确拼写所有者名称-它变得区分大小写。即:

someone.table"someone".tableSOMEONE.table

所有这些都标识同一个表。使用Informix,MODE ANSI数据库有一个轻微的复杂性,其中所有者名称通常转换为大写(Informix是例外)。也就是说,在MODE ANSI数据库(不常用)中,您可以编写:

CREATE TABLE someone.table ( ... )

并且系统曲库中的所有者名称将是“某人”,而不是“某人”。如果您将所有者名称用双引号括起来,它就像一个分隔标识符。使用标准SQL,分隔标识符可以在许多地方使用。使用Informix,您只能在所有者名称周围使用它们-在其他上下文中,Informix将单引号和双引号字符串视为字符串,而不是将单引号字符串分隔为字符串,将双引号字符串分隔为分隔标识符。(当然,只是为了完整性,有一个环境变量DELIMIDENT,可以设置为任何值,但Y是最安全的,以指示双引号始终围绕分隔的标识符,单引号始终围绕字符串。

请注意,MSSQLServer设法使用方括号中的[分隔标识符]。我觉得很奇怪,当然不是SQL标准的一部分。

这是另一个使用多个表获取源的示例:

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)SELECTPFl_EMP_CODE    ,PFl_DEPT_CODE   ,PFl_SEC         ,PFl_PROL_NO     ,PF_FM_SEQ       ,PF_SEQ_NO       ,PFl_SEP_TAG     ,PF_SOURCEFROM cesc_pf_stmt_ext,cesc_pfl_emp_masterWHERE pfl_sep_tag LIKE '0'AND pfl_emp_code=pf_emp_code(+);
COMMIT;

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

假设table1有两列。此查询应该有效:

INSERT INTO table1SELECT  col1, col2FROM    table2

这将不起作用(未指定col2的值):

INSERT INTO table1SELECT  col1FROM    table2

我使用的是MSSQL服务器,我不知道其他RDMS是如何工作的。

对于MicrosoftSQLServer,我建议学习解释MSDN上提供的SYNTAX。使用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的所有语法是没有意义的。

我更喜欢SQLServer 2008:

SELECT Table1.Column1, Table1.Column2, Table2.Column1, Table2.Column2, 'Some String' AS SomeString, 8 AS SomeIntINTO Table3FROM Table1 INNER JOIN Table2 ON Table1.Column1 = Table2.Column3

它省去了添加插入()集的步骤,您只需选择表中的值即可。

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

INSERT INTO TABLE_NAMESELECT COL1, COL2 ...FROM TABLE_YOU_NEED_TO_TAKE_FROM;

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

这对我有效:

insert into table1 select * from table2

这句话与Oracle的有点不同。

为了从另一个表中只获取多值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))

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

    Insert into Table1values(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

批量插入当您只想插入表的所需列时(表1):

    Insert into Table1 (Column1,Column2 ....Desired Column from Table1)Select Column1,Column2..desired column from #table2from #table2

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

INSERT INTO table1(desc, id, email)SELECT "Hello World", 3, email FROM table2 WHERE ...
select *into tmpfrom 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 TABLE1(COLUMN1, COLUMN2, COLUMN3, COLUMN4)VALUES (value1, value2,(SELECT COLUMN_TABLE2FROM TABLE2WHERE COLUMN_TABLE2 like "blabla"),value4);

而不是INSERT查询的VALUES部分,只需使用SELECT查询如下。

INSERT INTO table1 ( column1 , 2, 3... )SELECT col1, 2, 3... FROM table2
INSERT INTO yourtableSELECT fielda, fieldb, fieldcFROM donortable;

适用于所有DBMS

以下是如何从多个表中插入。这个特定的示例是在多对多场景中有一个映射表:

insert into StudentCourseMap (StudentId, CourseId)SELECT  Student.Id, Course.Id FROM Student, CourseWHERE Student.Name = 'Paddy Murphy' AND Course.Name = 'Basket weaving for beginners'

(我意识到匹配学生姓名可能会返回多个值,但你明白了。当Id是一个身份列并且未知时,匹配Id以外的东西是必要的。)

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

SELECT  *INTO    Table2FROM    Table1;

如果您使用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行的值计数不匹配”,当您最终弄清楚该怎么做时,您最终会写一篇琐碎的文章。

INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)SELECT  COLUMN_NAMEFROM    ANOTHER_TABLE_NAMEWHERE CONDITION;

从任何其他表插入多个记录的最佳方法。

INSERT  INTO dbo.Users( UserID ,Full_Name ,Login_Name ,Password)SELECT  UserID ,Full_Name ,Login_Name ,PasswordFROM    Users_Table(INNER JOIN / LEFT JOIN ...)(WHERE CONDITION...)(OTHER CLAUSE)

只需在INSERT中使用SELECT子句的括号。例如:

INSERT INTO Table1 (col1, col2, your_desired_value_from_select_clause, col3)VALUES ('col1_value','col2_value',(SELECT col_Table2 FROM Table2 WHERE IdTable2 = 'your_satisfied_value_for_col_Table2_selected'),'col3_value');

使用选择子查询插入的两种方法。

  1. 使用SELECT子查询返回带有一排的结果。
  2. 使用SELECT子查询返回带有多行的结果。

1. With SELECT子查询返回一行的结果的方法。

INSERT INTO <table_name> (<field1>, <field2>, <field3>)VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');

在这种情况下,它假设SELECT子查询根据WHERE条件或SQL聚合函数(如SUM、MAX、AVG等)仅返回一行结果

2. With SELECT子查询返回具有多行的结果的方法。

INSERT INTO <table_name> (<field1>, <field2>, <field3>)SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;

第二种方法适用于这两种情况。

正如Claude所说:

INSERT INTO table (column1, column2)VALUES (value1, value2);

Postgres支持下一个:创建表company.monitor2作为选择*fromcompany.monitor;

如果您想在表中插入一些数据而不想写入列名。

INSERT INTO CUSTOMER_INFO(SELECT CUSTOMER_NAME,MOBILE_NO,ADDRESSFROM OWNER_INFO cm)

桌子在哪里:

            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   |   RRB       |     +55   |   RR        ||

如果你先创建表,你可以这样使用;

  select * INTO TableYedek From Table

这个metot插入值,但与创建新复制表不同。