插入到......值中 ( SELECT ... FROM ... )

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

是否有一种来自SQL标准(例如SQL-92)的银弹语法,可以让我插入这些值,而不用担心底层数据库的问题?

对该问题的评论 (1)
解决办法

试试吧。

INSERT INTO table1 ( column1 )
SELECT  col1
FROM    table2  

这是标准的ANSI SQL,应该可以在任何DBMS上使用。

它肯定适用于。

  • Oracle
  • MS SQL Server
  • MySQL
  • Postgres
  • SQLite v3 *Teradata
  • DB2
  • Sybase
  • Vertica
  • HSQLDB
  • H2
  • AWS RedShift
  • SAP HANA
评论(0)

@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。

评论(2)

为了从另一张表的多值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))
评论(8)

我看到的两个答案在Informix中都能正常工作,而且基本上是标准的SQL。 就是说,这个符号。

INSERT INTO target_table[()] 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",而不是'某人&39;。 如果你把所有者的名字用双引号括起来,它的作用就像一个带分隔符的标识符。 在标准SQL中,分隔符可以用在很多地方。 在Informix中,你只能在所有者名称周围使用它们--在其他情况下,Informix将单引号和双引号字符串都视为字符串,而不是将单引号字符串作为字符串,将双引号字符串作为带分隔符的标识符。 (当然,为了完整起见,有一个环境变量,DELIMIDENT,可以设置为任何值,但Y是最安全的,以表明双引号总是围绕着带分隔符,单引号总是围绕着字符串)。)

请注意,MS SQL Server设法使用方括号中的[分隔符]。 对我来说,这看起来很奇怪,而且肯定不是SQL标准的一部分。

评论(0)

在第一个答案中,当我们只想从另一个表(在这个例子中只有一个表)中获取少量记录时,要添加一些东西。

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

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

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

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

评论(0)

用下面的 "SELECT "查询代替 "INSERT "查询中的 "VALUES "部分。

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

如果你在 "SELECT "部分为所有的列提供值,可以不在 "INSERT INTO "部分指定列。

比方说,table1有两列。 这个查询应该是可行的。

INSERT INTO table1
SELECT  col1, col2
FROM    table2

这是不可能的(没有指定col2的值)。

INSERT INTO table1
SELECT  col1
FROM    table2

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

评论(0)

这是另一个使用选择值的例子。

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

当表列顺序已知时,简单插入。

    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
评论(0)

插入到与select子查询的两种方法。

  1. 用select子查询返回结果为一行
  2. 使用SELECT子查询,返回多行的结果

1. 有SELECT子查询的方法,返回结果为一行**。

INSERT INTO  (, , ) 
VALUES ('DUMMY1', (SELECT  FROM  ),'DUMMY2');

在这种情况下,它假设SELECT子查询只返回基于WHERE条件或SQL聚合函数(如SUM, MAX, AVG等)的一行结果。 否则它将抛出错误

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

INSERT INTO  (, , ) 
SELECT 'DUMMY1', , 'DUMMY2' FROM ;

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

评论(0)

这里'是如何从多个表插入。 这个特殊的例子是在多对多的情况下,你有一个映射表。

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以外的地方进行匹配。)

评论(0)

下面是另一个使用多个表取源的例子。

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;
评论(0)

只要将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'
);
评论(0)
INSERT INTO yourtable
SELECT fielda, fieldb, fieldc
FROM donortable;

这适用于所有的DBMS

评论(0)

如果你想用 "SELECT * INTO "表插入所有的列,你可以尝试这样做。

SELECT  *
INTO    Table2
FROM    Table1;
评论(0)

这对我很有效。

insert into table1 select * from table2

这句话与甲骨文'的有些不同。

评论(0)

对于微软的SQL Server,我会推荐大家学习解释MSDN上提供的SYNTAX。 有了Google,寻找语法比以往任何时候都要容易。

对于这种特殊情况,可以尝试

谷歌。 插入网站:microsoft.com

第一个结果将是http://msdn.microsoft.com/en-us/library/ms174335.aspx。

如果您觉得难以理解页面顶部给出的语法,请向下滚动到示例("使用SELECT和EXECUTE选项从其他表中插入数据")。


[ WITH  [ ,...n ] ]
INSERT 
{
        [ TOP ( expression ) [ PERCENT ] ] 
        [ INTO ] 
        {  | rowset_function_limited 
          [ WITH (  [ ...n ] ) ]
        }
    {
        [ ( column_list ) ] 
        [ <output Clause> ]
        { VALUES ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n     ] 
        | derived_table       
评论(0)

其实我更喜欢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()集的步骤,你只需选择哪些值进入表格即可。

评论(0)
select *
into tmp
from orders

看起来不错,但只有在tmp不存在的情况下才有效(创建并填充)。 (SQL sever)

要插入到现有的临时表中。

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
评论(0)