SQL查询映射表以直接转换为JSON

时间:2019-01-25 09:18:11

标签: sql json postgresql

我有一个PostgreSQL映射表,其中包含公司员工之间的关系-团队负责人和团队成员。名为leaders的表如下所示:

leader_id | employee_id
    1     |      15
    1     |      21
    1     |      26
    2     |      76
    2     |      41

这两列都是person表的外键,其中包含namedob等信息。

目标是使用如下数据创建JSON:

{
  1: {name: "John Doe",
      person_id: 1,
      employees: {
        15: {name: "Oliver Queen",
            person_id: 15
        },
        21: {name: "Barry Alan",
            person_id: 21
        },
        26: {name: "Solomon Rondon",
            person_id: 26
        },
      }
  },
  2: {name: "Papi Hans",
      person_id: 2,
      employees: {
        76: {name: "Ashley Young",
            person_id: 76
        },
        41: {name: "Amberly Smith",
            person_id: 41
        }
      }
  },
}

通过编写带有两个联接的查询来将person表中的数据分别连接到leader_idemployee_id上,然后逐行迭代结果,我可以轻松地做到这一点创建JSON。

我的问题是是否有一种写查询的方法,以便以可用于JSON格式的格式显示结果,从而使我不必逐行迭代来构建它?如果有的话,那会更有效吗?

2 个答案:

答案 0 :(得分:4)

demo:db<>fiddle

str_extract
  1. 加入SELECT json_object_agg(person_id, -- 5 -- 4 json_build_object('name', name, 'person_id', person_id, 'employees', employees) ) FROM ( SELECT l.leader_id as person_id, p1.name as name, json_object_agg(l.employee_id, -- 3 json_build_object('name', p2.name, 'person_id', p2.id) -- 2 ) as employees FROM leader l JOIN person p1 ON l.leader_id = p1.id -- 1 JOIN person p2 ON l.employee_id = p2.id GROUP BY l.leader_id, p1.name ) s 表以获取名称
  2. 为每位员工创建JSON对象
  3. 通过按其负责人将这些json对象分组为一个JSON对象来聚合这些对象
  4. 使用员工为领导者创建JSON对象
  5. 将所有领导者对象汇总为一个JSON对象

在这种情况下,可以将(4)缩短为

person

进一步阅读:Postgres JSONPostgres JSON aggregates

答案 1 :(得分:1)

使用此人表:

                 Table "public.emp"
  Column   |  Type   | Collation | Nullable | Default 
-----------+---------+-----------+----------+---------
 person_id | integer |           | not null | 
 name      | text    |           | not null | 
Indexes:
    "emp_pkey" PRIMARY KEY, btree (person_id)
Referenced by:
    TABLE "leaders" CONSTRAINT "leaders_employee_id_fkey" FOREIGN KEY (employee_id) REFERENCES emp(person_id)
    TABLE "leaders" CONSTRAINT "leaders_leader_id_fkey" FOREIGN KEY (leader_id) REFERENCES emp(person_id)

例如,您可以这样查询:

SELECT json_agg(q)
FROM (SELECT le.person_id,
             le.name,
             json_agg(row_to_json(ee)) AS employees
      FROM emp le
        JOIN leaders l ON le.person_id = l.leader_id
        JOIN emp ee ON ee.person_id = l.employee_id
      GROUP BY le.person_id, le.name
     ) AS q;

                                                                             json_agg                                                             
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [{"person_id":1,"name":"John Doe","employees":[{"person_id":15,"name":"Oliver Queen"}, {"person_id":21,"name":"Barry Alan"}, {"person_id":26,"name":"Solomon Rondon"}]}, +
  {"person_id":2,"name":"Papi Hans","employees":[{"person_id":76,"name":"Ashley Young"}, {"person_id":41,"name":"Amberly Smith"}]}]
(1 row)