我正在写一份工作,将数据从旧设计转换为新设计。在此过程中,我需要从插入中获取ID到单独的表中,并在插入目标表中使用它,如下所示:
CREATE TABLE t1 {
t1_id BIGSERIAL,
col1 VARCHAR
};
CREATE TABLE t2 {
t2_id BIGSERIAL,
col2 VARCHAR, -- renamed from col1 to avoid confusion
t1_id BIGINT REFERENCES t1.t1_id
};
我定义了与以下形式匹配的SQL:
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, (SELECT * FROM ins)
FROM t3 a;
我希望它对..的SELECT * FROM ins
每一行都运行,SELECT
但是相反,它只运行一次,并将该值用于SELECT
。如何重组我的SQL以获得所需的行为?
编辑4
t1最终看起来像:
1,<NULL>
(1 row)
t2最终看起来像:
10,'a',1
11,'b',1 -- problem with id from t1 being 1
12,'c',1 -- problem with id from t1 being 1
.
.
我希望t1看起来像什么:
1,<NULL>
2,<NULL>
3,<NULL>
.
.
我希望t2看起来像什么:
10,'a',1
11,'b',2 -- id from t1 of 2
12,'c',3 -- id from t1 of 3
.
.
编辑 为了解决a_horse_with_no_name所说的内容,我也尝试了此操作(结果相同):
WITH ins AS (
INSERT INTO t1 (t1_id) VALUES (DEFAULT) RETURNING t1_id
) INSERT INTO t2
(col1, t1_id)
SELECT
a.val1, b.t1_id
FROM t3 a
JOIN ins b ON TRUE;
edit2
我只是尝试直接SEQUENCE
在查询中引用适当的方法,并且确实可以工作-但我根本不喜欢该解决方案(主要是因为我不喜欢对对象名称进行硬编码。)而不是直接引用SEQUENCE
I 的名称,我将不胜感激。:)
EDIT3
我想另一个解决办法是使用的PROCEDURE
做INSERT
,而不是一个CTE ..但我还是欣赏选项/建议。
我也尝试过,它仍然只计算一次值。但是也许我的加入并不十分正确。我将编辑我的帖子以显示我尝试过的操作。
—
Joishi Bodio
您只向其中插入一行
—
ypercubeᵀᴹ
t1
,而不为提供任何值t1.col1
。该列的数据应该从哪里来?被t1.col1
有关t2.col1
?
ypercube-t1.col1允许为NULL,并将在以后的过程中插入。因为我在实际的行值中将CTE引用为SUBSELECT,所以我认为它会被执行多次-但是事实证明我在这种假设下是不正确的。这就是为什么我在这里提出这个问题。在过去的几个小时中,我已经尝试过在google上寻找答案,但是还无法找到正确的答案。不,t1.col1与t2.col1不相关..对此感到抱歉。
—
Joishi Bodio
仍然
—
ypercubeᵀᴹ
INSERT INTO t1 (t1_id) VALUES (DEFAULT)
只将1行插入t1
。因此,它并不重要,如果你把ins
对的FROM
条款,并将其加入到t3
与否。您能告诉我们如何将2行(或更多行)插入t1
吗?更重要的是,您如何知道2个(或更多)t1.id
值中的哪个将与插入的行匹配t2
?
ins
和t3