将数据插入postgres中的相关表中

时间:2017-04-02 07:45:51

标签: postgresql

如果可能的话,我想在一个语句中插入一个对象(跨越一个主表和两个相关表)的所有数据。如果我只有一个相关的表,我假设我可以使用Common Table Expressions做这样的事情:

WITH foo AS (INSERT INTO foos VALUES (....) RETURNING id)
INSERT INTO bar VALUES (foo.id....)

我可以做这样的事情但是对于多个相关的桌子吗?

1 个答案:

答案 0 :(得分:0)

您可以根据需要将格式扩展到尽可能多的表。下面是一个包含一个主表和两个相关表的示例,以及几种获取最终结果的方法:

这些是使用的表格:

 CREATE TABLE main
 (
     main_id serial PRIMARY KEY,
     main_text text
 ) ;
 CREATE TABLE age
 (
     main_id integer REFERENCES main(main_id) PRIMARY KEY,
     birthdate date NOT NULL,
     CHECK(birthdate <= now())
 ) ;
 CREATE TABLE preferred_colours
 (
     main_id integer NOT NULL REFERENCES main(main_id),
     colour text NOT NULL,
     PRIMARY KEY(main_id, colour)
 ) ;

这是一个CTE,您可以在其中插入三个表格,并获得一些结果:

 WITH insert_main AS
 (
     INSERT INTO main (main_text)
     VALUES ('Main text')
     RETURNING main_text, main_id
 )
 , insert_age AS
 (
     INSERT INTO age (main_id, birthdate)
     VALUES ( (SELECT main_id FROM insert_main), '2017-01-01')
     RETURNING main_id, birthdate
 )
 , insert_colours AS
 (
     INSERT INTO preferred_colours (main_id, colour)
     SELECT
         main_id, colour
     FROM
         insert_main
         CROSS JOIN
         (SELECT 'blue' AS colour
          UNION 
          SELECT 'red'
          UNION
          SELECT 'green'
         ) AS colours
     RETURNING
         *
 )
 SELECT
      insert_main.main_id
     ,insert_main.main_text
     ,insert_age.birthdate
     ,(SELECT string_agg(colour, ', ' ORDER BY colour) 
       FROM insert_colours
      ) AS preferred_colours_list
 FROM
     insert_main 
     CROSS JOIN insert_age 

 main_id | main_text | birthdate  | preferred_colours_list
 ------: | :-------- | :--------- | :---------------------
       1 | Main text | 2017-01-01 | blue, green, red

dbfiddle here