插入...值 ( SELECT ...从 ... )

Insert into ... values ( SELECT ... FROM ... )

提问人:Claude Houle 提问时间:8/25/2008 最后编辑:BraiamClaude Houle 更新时间:7/13/2021 访问量:3319392

问:

我正在尝试使用另一个表的输入来制作一个表。尽管这对于许多数据库引擎来说是完全可行的,但我似乎总是难以记住当时引擎(MySQL、OracleSQL ServerInformixDB2)的正确语法。INSERT INTOSQL

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

语法 与数据库无关 ANSI-SQL-92

评论

2赞 Uğur Gümüşhan 1/3/2013
此示例有效:插入tag_zone选择 @tag,zoneid,GETDATE(),@positiong。STIntersects(多边形)来自区域

答:

2002赞 Claude Houle 8/25/2008 #1

尝试:

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

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

它绝对适用于:

  • 神谕
  • MS SQL 服务器
  • MySQL数据库
  • Postgres的
  • SQLite v3
  • Teradata的
  • EBS光学显微镜
  • Sybase
  • Vertica(维蒂卡酒店)
  • HSQLDB数据库
  • H2型
  • AWS RedShift的
  • SAP HANA的
  • 谷歌扳手

评论

0赞 AmigoJack 7/8/2021
我非常怀疑他们是否都立即支持它 - 只有 SQLite 有最低版本,但它对其他人来说也很有趣,尤其是 ORACLE。
0赞 RJD 9/1/2021
@MindRoasterMir 你不能那样做。如果执行插入操作,则会在表中创建一个新行,因此不能有可以与之比较的现有行 (c.pageno = t.pageno)。您可能正在寻找 UPDATE 或 MERGE (MS Sql)
0赞 sametcilli 2/10/2022
如果要根据主键或唯一索引处理重复行,则可以使用IGNORE选项,例如INSERT IGNORE INTO table SELECT * FROM another_table
1220赞 travis 8/25/2008 #2

Claude Houle's answer: 应该可以正常工作,您还可以拥有多个列和其他数据:

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 一起使用。

评论

1赞 VijayRana 3/17/2016
如果 where 条件更改为 table2.country 并返回大于 1 的行数,该怎么办?我在这里遇到了类似的问题:stackoverflow.com/questions/36030370/......
1赞 Maximilian Riegler 4/11/2016
插入多行应该没有问题。
0赞 Mahesh Jamdade 2/24/2020
我们是否有必要插入表格的所有列
1赞 travis 2/25/2020
@maheshmnj否,则只需要包含设置为 NOT NULL 且没有默认值的列,任何其他列都将设置为其默认值或 NULL
0赞 Farah Nazifa 11/1/2021
不适用于 AWS redshift - 出现错误 - XX000:字符类型的值太长
75赞 Jonathan Leffler 9/28/2008 #3

我看到的两个答案在 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 标准使用术语 schema 来表示 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 标准的一部分。

17赞 SWATI BISWAS 6/6/2012 #4

下面是另一个示例,其中使用多个表获取源:

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;
32赞 northben 10/16/2012 #5

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

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

INSERT INTO table1
SELECT  col1, col2
FROM    table2

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

INSERT INTO table1
SELECT  col1
FROM    table2

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

13赞 Faiz 10/18/2012 #6

对于 Microsoft SQL Server,我建议学习解释 MSDN 上提供的语法。有了 Google,寻找语法比以往任何时候都更容易。

对于这种特殊情况,请尝试

谷歌:插入网站:微软.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的所有语法是没有意义的。

评论

1赞 reggaeguitar 1/24/2020
我完全不同意,多年来我一直在研究这些语法语句,但仍然无法弄清楚它们的正面或反面。示例更有用
0赞 reggaeguitar 1/24/2020
这不是一个答案,而是说“阅读文档”,仅此而已
14赞 Grungondola 3/22/2013 #7

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

37赞 Santhosh 4/1/2013 #8

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

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

我使用过的每个数据库都遵循以下语法,即 、 、 、DB2SQL ServerMY SQLPostgresQL

14赞 elijah7 11/20/2013 #9

这对我有用:

insert into table1 select * from table2

这句话和甲骨文的有点不同。

228赞 kylieCatt 1/11/2014 #10

为了从另一个表中仅获取多个值中的一个值,我在 SQLite3 中执行了以下操作:INSERT

INSERT INTO column_1 ( val_1, val_from_other_table ) 
VALUES('val_1', (SELECT  val_2 FROM table_2 WHERE val_2 = something))

评论

4赞 7/23/2014
澄清一下:这对于 SQLite3 来说是不正确的。根据文档,源数据是 要么是语句,而不是两者兼而有之。INSERTVALUESSELECT
2赞 Banjocat 10/21/2014
确实,文档没有列出它,但它确实有效。无论如何,我认为使用 select 语句而不是 values 确实使它更具可读性。
2赞 Luchostein 11/24/2015
它适用于在行中指定一个值,但更一般的情况需要获取大量行。
0赞 9/16/2016
如果val_1在行之间没有变化,那么以下语法可能在 SQLite3 中有效?select 'foo',从some_table some_column - 适用于 SQLServer 2014
2赞 zapl 7/4/2018
文档确实列出了这个(现在?):这个语法是,[expr] 中的路径之一是 - 请注意,select 语句周围的 paranthesis 是必需的(意思是可选的)INSERT INTO ... VALUES ([expr], [expr], ...){{NOT} EXISTS} ([select-stmt]){}
21赞 RameezAli 2/13/2014 #11

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

    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
25赞 Sarvar Nishonboyev 3/20/2014 #12

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

INSERT INTO table1(desc, id, email) 
SELECT "Hello World", 3, email FROM table2 WHERE ...
10赞 Pavel 5/18/2014 #13
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
49赞 Weslor 4/10/2015 #14

要在第一个答案中添加一些内容,当我们只想从另一个表中获取几条记录时(在本例中只有一条):

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

评论

8赞 snowfox 4/26/2016
此方法仅适用于仅选择一列的子查询。在多列子查询的情况下,将引发错误“子查询必须仅返回一列”。那就采用@travis的答案吧。
39赞 logan 4/21/2015 #15

只需使用如下所示的查询,而不是部分查询。VALUESINSERTSELECT

INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
14赞 Matt 5/20/2015 #16
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

这适用于所有 DBMS

17赞 Ciarán Bruen 3/23/2016 #17

以下是从多个表中插入的方法。在此特定示例中,您可以在多对多方案中拥有映射表:

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 以外的其他内容。

15赞 Bharath theorare 6/17/2016 #18

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

SELECT  *
INTO    Table2
FROM    Table1;

评论

0赞 Markus Pscheidt 3/15/2022
H2 不支持
5赞 Sebastian 6/9/2017 #19

如果使用 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行的值计数不匹配”,当您最终弄清楚如何处理它时,您最终会写出一篇微不足道的文章。

评论

7赞 Quality Catalyst 11/21/2017
问题是“使用另一个表的输入插入到一个表中”。你的回答是如何解决这个问题的?
3赞 Darth Scitus 2/15/2018
呃,不要对他太苛刻。当我在谷歌上搜索时,它回答了我的问题。@QualityCatalyst
13赞 Gaurav 2/14/2018 #20
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT  COLUMN_NAME
FROM    ANOTHER_TABLE_NAME 
WHERE CONDITION;
12赞 Manish Vadher 6/7/2018 #21

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

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)
26赞 Dasikely 9/24/2018 #22

只需在 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'
);
69赞 Mohammed Safeer 4/4/2019 #23

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

  1. 使用 SELECT 子查询返回一行的结果。
  2. 使用 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>;

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

评论

0赞 Sithija Piyuman Thewa Hettige 2/13/2023
我想将 RETURNING 与此一起使用以返回插入记录的特定列?我如何做到这一点@Mohammed更安全任何投入?
0赞 Chimdi 9/1/2023
@SithijaPiyumanThewaHettige您可以执行以下操作: INSERT INTO tablename (col1, col2) SELECT field1, field2 FROM tablename 返回 col1, col2 maria db 支持从版本 10.5.0 开始 您可以查看文档 mariadb.com/kb/en/insertreturning
1赞 Miroslav Savel 12/12/2019 #24

在 informix 中,它的工作方式正如 Claude 所说:

INSERT INTO table (column1, column2) 
VALUES (value1, value2);    
1赞 Kazakov Vsevolod 4/1/2020 #25

Postgres 支持 next: 创建表 company.monitor2 as select * from company.monitor;

8赞 S.M.Fazle Rabbi 6/1/2020 #26

如果要在表中插入一些数据,但又不想写入列名。

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        ||
3赞 Serdin Çelik 7/13/2021 #27

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

  select * INTO TableYedek From Table

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

评论

1赞 Raj G 8/16/2021
如果将整个表另存为备份,请使用此查询。select * INTO TableYedek_Backup From TableYedek