1657

我正在尝试INSERT INTO使用来自另一个表的输入来创建一个表。尽管这对于许多数据库引擎来说是完全可行的,但我似乎总是很难记住当时SQL引擎(MySQLOracleSQL ServerInformixDB2)的正确语法。

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

4

27 回答 27

1818

尝试:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

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

它绝对适用于:

  • 甲骨文
  • 微软 SQL 服务器
  • MySQL
  • Postgres
  • SQLite v3
  • 太极数据
  • DB2
  • 赛贝斯
  • 垂直
  • 数据库
  • H2
  • AWS 红移
  • SAP HANA
  • 谷歌扳手
于 2008-08-25T12:47:54.460 回答
1126

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。

于 2008-08-25T14:11:15.353 回答
193

为了从另一个表中获取多值中的一个值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))
于 2014-01-10T23:46:12.247 回答
69

我看到的两个答案都特别适用于 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”,而不是“某人”。如果将所有者名称括在双引号中,则它的作用类似于分隔标识符。使用标准 SQL,分隔标识符可以在很多地方使用。使用 Informix,您只能在所有者名称周围使用它们 —— 在其他上下文中,Informix 将单引号和双引号字符串都视为字符串,而不是将单引号字符串分隔为字符串,将双引号字符串分隔为定界标识符。(当然,为了完整起见,有一个环境变量 DELIMIDENT 可以设置 - 为任何值,但 Y 是最安全的 - 表示双引号始终围绕分隔标识符,单引号始终围绕字符串。)

请注意,MS SQL Server 设法使用括在方括号中的 [delimited identifiers]。它在我看来很奇怪,而且肯定不是 SQL 标准的一部分。

于 2008-09-28T03:18:41.750 回答
50

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

  1. 使用 SELECT 子查询返回One row的结果。
  2. 使用 SELECT 子查询返回多行结果。

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

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

在这种情况下,它假设 SELECT 子查询根据 WHERE 条件或 SUM、MAX、AVG 等 SQL 聚合函数仅返回一行结果。否则会抛出错误

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

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

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

于 2019-04-04T04:09:13.230 回答
45

要在第一个答案中添加一些内容,当我们只需要另一个表中的几条记录时(在此示例中只有一条):

INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4) 
VALUES (value1, value2, 
(SELECT COLUMN_TABLE2 
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
于 2015-04-09T17:15:42.433 回答
36

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

INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
于 2015-04-21T10:31:32.007 回答
35

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

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

我使用的每个数据库都遵循这种语法DB2SQL ServerMY SQL,、、、、PostgresQL

于 2013-04-01T10:09:09.297 回答
30

INSERT INTO如果您为部件中的所有列提供值,则无需指定部件中的列即可完成此操作SELECT

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

INSERT INTO table1
SELECT  col1, col2
FROM    table2

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

INSERT INTO table1
SELECT  col1
FROM    table2

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

于 2012-10-16T14:19:52.863 回答
23

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

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...
于 2014-03-20T09:12:35.037 回答
20

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

    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
于 2014-02-13T12:23:26.637 回答
20

只需使用括号将SELECT子句插入 INSERT。例如像这样:

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'
);
于 2018-09-24T09:25:16.353 回答
16

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

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;
于 2012-06-06T12:41:10.260 回答
16

这是从多个表中插入的方法。此特定示例是在多对多场景中拥有映射表的地方:

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

于 2016-03-23T14:31:52.010 回答
14

如果你想使用SELECT * INTO表格插入所有列,你可以试试这个。

SELECT  *
INTO    Table2
FROM    Table1;
于 2016-06-17T10:28:45.907 回答
13

我实际上更喜欢 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 () 集的步骤,您只需选择表中的值即可。

于 2013-03-22T14:57:06.207 回答
13

这对我有用:

insert into table1 select * from table2

这句话与Oracle的有点不同。

于 2013-11-20T12:19:28.200 回答
13
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

这适用于所有 DBMS

于 2015-05-20T08:44:14.110 回答
12

对于 Microsoft SQL Server,我建议学习解释 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 的所有语法是没有意义的。

于 2012-10-17T16:56:44.743 回答
12
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;
于 2018-02-13T16:35:20.867 回答
10

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

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)
于 2018-06-07T06:59:35.390 回答
9
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
于 2014-05-17T20:28:32.637 回答
7

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

INSERT INTO CUSTOMER_INFO
   (SELECT CUSTOMER_NAME,
           MOBILE_NO,
           ADDRESS
      FROM 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   |   RR
      B       |     +55   |   RR        ||
于 2020-06-01T15:11:29.430 回答
4

如果您使用 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 行的值数不匹配”,当您最终弄清楚该怎么做时,您最终会写一篇微不足道的帖子。

于 2017-06-09T03:51:51.037 回答
2

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

  select * INTO TableYedek From Table

此metot 插入值但与创建新副本表不同。

于 2021-07-13T15:27:13.200 回答
0

在 informix 中,它像 Claude 所说的那样工作:

INSERT INTO table (column1, column2) 
VALUES (value1, value2);    
于 2019-12-12T07:59:06.883 回答
0

Postgres 支持 next: create table company.monitor2 as select * from company.monitor;

于 2020-04-01T13:48:52.263 回答