一组 with 后的多个插入查询

Yog*_*sch 1 postgresql insert subquery postgresql-10

我正在尝试以一种可重现的方式用一些测试数据填充数据库。

假设(一个过于简化的示例)三个基表:name、city、job 和两个关系表:name-city 和 name-job。我需要在三个基表中的每一个中创建一个条目,并使用上述条目在两个关系表中创建条目。

我已经拥有了一种使用一系列with查询在 3 个基表中创建条目并将值插入到一个关系表中的方法。

with x as 
(INSERT INTO "public"."name" VALUES(DEFAULT) RETURNING "id"),
y as 
(INSERT INTO "public"."job" VALUES(DEFAULT) RETURNING "id"),
z as 
(INSERT INTO "public"."city" VALUES(DEFAULT) RETURNING "id")

INSERT INTO "public"."name-job"("name", "job")  
select x.id, y.id from x,y;
Run Code Online (Sandbox Code Playgroud)

我真的想添加第二个插入语句

INSERT INTO "public"."name-city"("name", "city")  
select x.id, z.id from x,z;
Run Code Online (Sandbox Code Playgroud)

第一次插入后,但不知道如何。我曾尝试用逗号分隔两个插入语句,并将它们括在括号中,然后用逗号分隔它们,以及其他一些方法,但没有任何效果。

使用带有第二个插入的全新语句并不完全是一种选择,因为我需要使用相同的 x、y、z 值。鉴于我缺乏专业知识/经验,我完全有可能遗漏了一些明显的东西......所以任何关于我如何做到这一点的想法,理想情况下,没有高度复杂的工具,将是最受欢迎的。

FWIW,我正在使用 Postgres (10.x)

ype*_*eᵀᴹ 5

您需要将INSERT INTO "name-job"放入另一个 CTE。您也可以将最后一个插入内容放入"name-city"CTE,并添加一个SELECT以获取所有插入的 id(以及您需要从插入的行中获取的任何其他内容)。

WITH 
  x AS 
  (INSERT INTO public.name VALUES (DEFAULT) RETURNING id),
  y AS 
  (INSERT INTO public.job VALUES (DEFAULT) RETURNING id),
  z AS
  (INSERT INTO public.city VALUES (DEFAULT) RETURNING id),
  xy AS
  (INSERT INTO public."name-job" (name, job)  
   SELECT x.id, y.id FROM x,y
   RETURNING name, job),
  xz AS
  (INSERT INTO public."name-city" (name, city)  
   SELECT x.id, z.id FROM x,z
   RETURNING name, city)
SELECT x.id, y.id, z.id, xy.*, xz.*
FROM x, y, z, xy, xz ;
Run Code Online (Sandbox Code Playgroud)
  • 如果要在表中插入多于一行,查询将需要更复杂(使用连接而不是隐式交叉连接)。
  • 表和列的命名将是一个不断的麻烦和痛苦。如果所有表名和列名都是小写并且不使用特殊字符(如您使用的破折号),我发现在 Postgres 中它更容易。只有下划线和数字。这样就可以避免在任何地方使用双引号。