如何从Postgres中的多个相关表中检索数据?

时间:2015-12-23 15:49:26

标签: sql postgresql

Postgres 9.4
4个表之间具有多对多的关系。我已经创建了额外的表来实现关系:

CREATE TABLE "public"."relation" (
  "id" uuid NOT NULL DEFAULT uuid_generate_v4(),
  "table1" uuid NOT NULL,
  "table2" uuid,
  "table3" uuid,
  "table4" uuid,
  "approved" bool DEFAULT true,
  CONSTRAINT "relation_pkey" PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE,
  CONSTRAINT "table1" FOREIGN KEY ("table1") REFERENCES "public"."table1" ("id") ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE,
  CONSTRAINT "table2" FOREIGN KEY ("table2") REFERENCES "public"."table2" ("id") ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE,
  CONSTRAINT "table3" FOREIGN KEY ("table3") REFERENCES "public"."table3" ("id") ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE,
  CONSTRAINT "table4" FOREIGN KEY ("table4") REFERENCES "public"."table4" ("id") ON UPDATE NO ACTION ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
)
WITH (OIDS=FALSE);
ALTER TABLE "public"."relation" OWNER TO "postgres";

我需要从table1检索单行,包括来自其他表的所有相关行作为JSON对象。 这里我从relation表中检索了行:

SELECT t.*
   FROM ( SELECT table1.id,
            (select row_to_json(relations.*) as array_to_json
              from(select * from relation where table1 = table1.id) relations
            ) as relations,

           from public.table1) t

但我无法弄清楚如何通过relation表中的数据有效地从相关表中检索行。

可能这是有价值的信息:
relation表中的每一行只包含两个关系。例如,它可能包含与table1和table2的关系。其余列是空的(当然除了id)。 表table1,2,3,4中的每一行的关系少于10个 我想要检索这样的东西:

{
    id: table1.id,
    name: table1.name,
    related_items: [
        {id: table2.id, name: table2.name},
        {id: table4.id, name: table4.name},
        {id: table3.id, name: table3.name},
        {id: table2.id, name: table2.name},
        {id: table3.id, name: table3.name},
    ]
}

感谢您的时间!

1 个答案:

答案 0 :(得分:0)

SELECT ROW_TO_JSON(T)
FROM    (
        SELECT t1.id,
               t1.name,
               array_to_json(array((
                 select case when t2.id is not null then row_to_json(t2) 
                             when t3.id is not null then row_to_json(t3) 
                             when t4.id is not null then row_to_json(t4) 
                        end
                 from   public.relation r 
                 LEFT JOIN public.table1 t2 on r.table2 = t2.id
                 LEFT JOIN public.table1 t3 on r.table3 = t3.id
                 LEFT JOIN public.table1 t4 on r.table4 = t4.id
                 where  r.table1 = t1.id
               ))) related_items
        FROM   public.table1 t1
       ) T