插入...值(SELECT ... FROM ...)
-
09-06-2019 - |
解决方案
尝试:
INSERT INTO table1 ( column1 )
SELECT col1
FROM table2
这是标准 ANSI SQL,应该适用于任何 DBMS
它绝对适用于:
- 甲骨文
- 微软SQL服务器
- MySQL
- Postgres
- SQLite v3
- 泰拉数据
- 数据库2
- 赛贝斯
- 维蒂卡
- HSQL数据库
- 氢2
- AWS 红移
- SAP HANA
其他提示
@影子_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 语法有很好的支持,并且,据我所知,在这种表示法上它可以正常工作。)列列表是可选的,但按顺序指示目标列,因此 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”,而不是“someone”。如果将所有者名称括在双引号中,则它的作用类似于分隔标识符。对于标准 SQL,分隔标识符可以在很多地方使用。使用 Informix,您只能在所有者名称周围使用它们——在其他上下文中,Informix 将单引号和双引号字符串都视为字符串,而不是将单引号字符串视为字符串,将双引号字符串视为分隔标识符。(当然,为了完整起见,有一个环境变量 DELIMIDENT,可以设置为任何值,但 Y 是最安全的 - 指示双引号始终包围定界标识符,而单引号始终包围字符串。)
请注意,MS SQL Server 设法使用方括号括起来的[分隔标识符]。它对我来说看起来很奇怪,并且肯定不是 SQL 标准的一部分。
大多数数据库都遵循基本语法,
INSERT INTO TABLE_NAME
SELECT COL1, COL2 ...
FROM TABLE_YOU_NEED_TO_TAKE_FROM
;
我使用过的每个数据库都遵循这个语法,即 DB2
, SQL Server
, MY SQL
, PostgresQL
要在第一个答案中添加一些内容,当我们只需要另一个表中的几条记录(在本例中只有一条)时:
INSERT INTO TABLE1
(COLUMN1, COLUMN2, COLUMN3, COLUMN4)
VALUES (value1, value2,
(SELECT COLUMN_TABLE2
FROM TABLE2
WHERE COLUMN_TABLE2 like "blabla"),
value4);
这可以在不指定列的情况下完成 INSERT INTO
如果您要为中的所有列提供值,则部分 SELECT
部分。
假设 table1 有两列。这个查询应该有效:
INSERT INTO table1
SELECT col1, col2
FROM table2
这不起作用(价值 col2
未指定):
INSERT INTO table1
SELECT col1
FROM table2
我正在使用 MS SQL Server。我不知道其他 RDMS 是如何工作的。
代替 VALUES
部分 INSERT
查询,只需使用 SELECT
查询如下。
INSERT INTO table1 ( column1 , 2, 3... )
SELECT col1, 2, 3... FROM table2
这是使用 select 值的另一个示例:
INSERT INTO table1(desc, id, email)
SELECT "Hello World", 3, email FROM table2 WHERE ...
当表列顺序已知时简单插入:
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
这是使用多个表获取源的另一个示例:
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 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;
这对我有用:
insert into table1 select * from table2
这句话和Oracle的有点不一样。
对于 Microsoft SQL Server,我建议学习解释 MSDN 上提供的语法。有了 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。在我看来,记住所有产品的所有语法是没有意义的。
实际上我更喜欢 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 () 集的步骤,您只需选择将哪些值放入表中即可。
只需使用括号即可 选择 子句插入 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'
);
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
从任何其他表插入多条记录的最佳方法。
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)
INSERT INTO FIRST_TABLE_NAME (COLUMN_NAME)
SELECT COLUMN_NAME
FROM ANOTHER_TABLE_NAME
WHERE CONDITION;
使用 select 子查询插入的两种方法。
- 使用 SELECT 子查询返回结果 一排.
- 使用 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>;
第二种方法适用于这两种情况。
如果您使用 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 行的值计数不匹配”,当您最终弄清楚该怎么做时,您最终会写一篇微不足道的文章。