SQL PostgreSQL:在插入中进行子选择
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13016851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PostgreSQL: Sub-select inside insert
提问by Bantha Fodder
I have a table called map_tags
:
我有一张桌子叫map_tags
:
map_id | map_license | map_desc
And another table (widgets
) whose records contains a foreign key reference (1 to 1) to a map_tags
record:
另一个表 ( widgets
) 的记录包含对记录的外键引用(1 到 1)map_tags
:
widget_id | map_id | widget_name
Given the constraint that all map_license
s are unique (however are not set up as keys on map_tags
), then if I have a map_license
and a widget_name
, I'd like to perform an insert on widgets
all inside of the same SQL statement:
考虑到所有map_license
s 都是唯一的约束(但是没有设置为 上的键map_tags
),那么如果我有 amap_license
和 a widget_name
,我想widgets
在同一个 SQL 语句的所有内部执行插入:
INSERT INTO
widgets w
(
map_id,
widget_name
)
VALUES (
(
SELECT
mt.map_id
FROM
map_tags mt
WHERE
// This should work and return a single record because map_license is unique
mt.map_license = '12345'
),
'Bupo'
)
I believeI'm on the right track but know right off the bat that this is incorrect SQL for Postgres. Does anybody know the proper way to achieve such a single query?
我相信我在正确的轨道上,但马上就知道这对于 Postgres 来说是不正确的 SQL。有人知道实现这种单一查询的正确方法吗?
回答by gahooa
Use the INSERT INTO SELECT
variant, including whatever constants right into the SELECT
statement.
使用INSERT INTO SELECT
变体,包括SELECT
语句中的任何常量。
The PostgreSQL INSERT
syntax is:
PostgreSQLINSERT
语法是:
INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
Take note of the queryoption at the end of the second line above.
请注意上面第二行末尾的查询选项。
Here is an example for you.
这是一个例子。
INSERT INTO
widgets
(
map_id,
widget_name
)
SELECT
mt.map_id,
'Bupo'
FROM
map_tags mt
WHERE
mt.map_license = '12345'
回答by Clodoaldo Neto
INSERT INTO widgets
(
map_id,
widget_name
)
SELECT
mt.map_id, 'Bupo'
FROM
map_tags mt
WHERE
mt.map_license = '12345'
回答by J.M.I. MADISON
Quick Answer:You don't have "a single record" you have a "set with 1 record" If this were javascript: You have an "array with 1 value" not "1 value".
快速回答:您没有“单个记录”,您有一个“设置 1 个记录”如果这是 javascript:您有一个“具有 1 个值的数组”而不是“1 个值”。
In your example, one record may be returned in the sub-query, but you are still trying to unpack an "array" of records into separate actual parameters into a place that takes only 1 parameter.
在您的示例中,子查询中可能会返回一条记录,但您仍在尝试将记录的“数组”解包为单独的实际参数,并将其放入仅包含 1 个参数的位置。
It took me a few hours to wrap my head around the "why not". As I was trying to do something very similiar:
我花了几个小时才把头放在“为什么不”上。当我试图做一些非常相似的事情时:
Here are my notes:
以下是我的笔记:
tb_table01: (no records)
+---+---+---+
| a | b | c | << column names
+---+---+---+
tb_table02:
+---+---+---+
| a | b | c | << column names
+---+---+---+
|'d'|'d'|'d'| << record #1
+---+---+---+
|'e'|'e'|'e'| << record #2
+---+---+---+
|'f'|'f'|'f'| << record #3
+---+---+---+
--This statement will fail:
INSERT into tb_table01
( a, b, c )
VALUES
( 'record_1.a', 'record_1.b', 'record_1.c' ),
( 'record_2.a', 'record_2.b', 'record_2.c' ),
-- This sub query has multiple
-- rows returned. And they are NOT
-- automatically unpacked like in
-- javascript were you can send an
-- array to a variadic function.
(
SELECT a,b,c from tb_table02
)
;
Basically, don'tthink of "VALUES" as a variadicfunction that can unpack an array of records. There is no argument unpacking here like you would have in a javascript function. Such as:
基本上,不要将“ VALUES”视为 可以解压缩记录数组的可变参数函数。这里没有像在 javascript 函数中那样解包的参数。如:
function takeValues( ...values ){
values.forEach((v)=>{ console.log( v ) });
};
var records = [ [1,2,3],[4,5,6],[7,8,9] ];
takeValues( records );
//:RESULT:
//: console.log #1 : [1,2,3]
//: console.log #2 : [4,5,7]
//: console.log #3 : [7,8,9]
Back to your SQL question:
回到你的 SQL 问题:
The reality of this functionality not existing does not change just because your sub-selection contains only one result. It is a "set with one record" not "a single record".
不存在此功能的现实不会因为您的子选择只包含一个结果而改变。它是一个“单条记录”,而不是“单条记录”。