我有一个名为map_tags
的表格:
map_id | map_license | map_desc
另一个表(widgets
),其记录包含对map_tags
记录的外键引用(1到1):
widget_id | map_id | widget_name
鉴于所有map_license
都是唯一的约束(但未在map_tags
上设置为关键字),那么如果我有map_license
和widget_name
,我想在同一个SQL语句中的widgets
上执行插入:
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'
)
我相信我在正确的轨道上,但是马上知道这对于Postgres来说这是不正确的SQL。有没有人知道实现这种单一查询的正确方法?
答案 0 :(得分:32)
使用INSERT INTO SELECT
变体,包括SELECT
语句中的任何常量。
PostgreSQL INSERT
语法是:
INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }
[ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]
记下上面第二行末尾的查询选项。
这是一个例子。
INSERT INTO
widgets
(
map_id,
widget_name
)
SELECT
mt.map_id,
'Bupo'
FROM
map_tags mt
WHERE
mt.map_license = '12345'
答案 1 :(得分:25)
INSERT INTO widgets
(
map_id,
widget_name
)
SELECT
mt.map_id, 'Bupo'
FROM
map_tags mt
WHERE
mt.map_license = '12345'
答案 2 :(得分:0)
快速解答: 您没有“ 单个记录”,而没有“ 包含1条记录” 如果是javascript:您有一个“值为1的数组”而不是“值为1”。
在您的示例中,子查询中可能返回一条记录, 但您仍在尝试将记录的“数组”拆成单独的包装 实际参数放到只需要一个参数的地方。
我花了几个小时把头包在“为什么不”上。 当我尝试做一些非常相似的事情时:
这是我的笔记:
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
)
;
基本上,不要认为“ 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]
返回您的SQL问题:
此功能不存在的现实不会改变 只是因为您的子选择只包含一个结果。它是 “ 具有一个记录的设置”而不是“ 单个记录”。