我有三张表,我已将其缩写为以下
create table top (top_id serial, top_name text);
create table mid (mid_id serial, top_id integer, mid_name text);
create table bot (bot_id serial, mid_id integer, bot_name text);
我想要实现的是
因此,最终结果可能看起来像
top
----
1, first_top
2, second_top
mid
---
1, 1, first_mid_for_first_top
2, 1, second_mid_for_first_top
3, 2, first_mid_for_second_top
bot
---
1, 1, first_bot_for_first_mid
2, 1, second_bot_for_first_mid
3, 3, first_bot_for_third_mid
我的第一种方法是尝试使用一堆嵌套的CTE,但我无法将其转换为有效的语法(考虑到这一点,我认为它不是正确的方法)。
我的第二种方法是尝试将值存储到某种变量中,但我不知道如何在pg命令行工具之外执行此操作。
我所追求的是类似于
的东西top_id_one = insert into top(null, 'first_top') returning top_id
mid_id_one = insert into mid(null, top_id_one, 'first_mid_for_first_top) returning mid_id
insert into bot(null, mid_id_one, 'first_bot_for_first_mid')
纯粹的sql"例如,我可以粘贴到PG管理员。
我意识到上面的例子中存在一些问题(例如使用' top'作为表名)。我的探索已经避免了这些问题,但我试图找到能够使我的例子有意义的表名。
答案 0 :(得分:2)
您可以通过对插入mid_id
的行进行编号,选择使用哪个bot
将值插入mid
。
使用这些行号(rn
)来标识插入bot
的值:
with top_ins as (
insert into top (top_name)
values ('first_top')
returning top_id
),
mid_ins as (
insert into mid (top_id, mid_name)
select top_id, name
from (
values
('first_mid'),
('second_mid')
) v(name)
cross join top_ins
returning mid_id
),
mid_ins_rn as (
select mid_id, row_number() over() rn
from mid_ins
order by 1
)
insert into bot (mid_id, bot_name)
select mid_id, name
from (
values
(1, 'first_bot_for_first_mid'),
(1, 'second_bot_for_first_mid'),
(2, 'first_bot_for_second_mid')
) v(rn, name)
join mid_ins_rn
using (rn);
结果:
select * from top;
top_id | top_name
--------+-----------
1 | first_top
(1 row)
select * from mid;
mid_id | top_id | mid_name
--------+--------+------------
1 | 1 | first_mid
2 | 1 | second_mid
(2 rows)
select * from bot;
bot_id | mid_id | bot_name
--------+--------+--------------------------
1 | 1 | first_bot_for_first_mid
2 | 1 | second_bot_for_first_mid
3 | 2 | first_bot_for_second_mid
(3 rows)
答案 1 :(得分:1)
如果您可以按顺序运行sql语句,则可以使用序列的当前值(弹出表中最后一个插入的id的currval)来获取top,mid,bot的值:
String s = (String) value;
这应该给出确切的结果,您在示例中显示了最终结果。