Select table 作为 json 数组

Select table as json array

我在 PostgreSQL 中有三个 table:ABC
我想从 table A 中获取具有特定 id 的行,以及来自 table 的 BC 中匹配 id 汇总 JSON.

例如:

Table A                     Table B                Table C
---------------------------------------------------------------
id / colum1  / colum2       id/  colum 1          id / column1
1  someValue, somValue      1   someVal1           1   someVal1
                            1   someVal2           1   someVal2

id = 1 的预期输出为:

a.column1   a.column2       ARRAY_JSON_B              ARRAY_JSON_C       
------------------------------------------------------------------------------
someValue    someValue   [{colum1:'someVal1'},       [{colum1:'someVal1'},
                         {colum1:'someVal2'}]        {colum1:'someVal2'}]
select
        a.*,
        to_json(array(select b from b where b.id = a.id)) array_json_b,
        to_json(array(select c from c where c.id = a.id)) array_json_c
    from a
        where
            a.id = 1;

希望你的Postgresql版本是9.3或者更高。有一个聪明的函数 to_json 可以将任何东西转换为 json。所以我们从 b 中获取所有相关行的数组并将其转换。与 c.

相同

这需要 Postgres 9.3 或更高版本。

简单案例

我建议使用用于此目的的更简单的 json_agg(),在 LATERAL 连接中:

SELECT *
FROM   a
LEFT JOIN LATERAL (SELECT json_agg(b) AS array_json_b FROM b WHERE id = a.id) b ON true
LEFT JOIN LATERAL (SELECT json_agg(c) AS array_json_c FROM c WHERE id = a.id) c ON true
WHERE  id = 1;

LEFT JOIN LATERAL ... ON true 保留结果中联接左侧没有匹配项的行。详情:

细微差别:此查询 returns NULL 在 bc 中找不到匹配项, returns 而是一个空数组。可能重要也可能不重要。

实际答案

问题中的示例从结果中排除了 bc 中多余的 id 列 - 这是有道理的。为此,您不能使用@stas 的简单相关子查询。虽然它仍然 对单个列而不是整行有效 ,但它会丢失列名并生成一个简单的数组。此外,它不适用于超过一列。

单个选定列使用json_object_agg()(这也允许自由选择标签名称):

SELECT *
FROM   a
LEFT   JOIN LATERAL (
   SELECT json_object_agg('colum1', colum1) AS array_json_b
   FROM   b WHERE id = a.id
   ) b ON true
LEFT   JOIN LATERAL (
   SELECT json_object_agg('colum1', colum1) AS array_json_c
   FROM   c WHERE id = a.id
   ) c ON true
WHERE  id = 1;

或对 any 选择使用子选择(本例中为 col1col2):

SELECT *
FROM   a
LEFT   JOIN LATERAL (
   SELECT json_agg(x) AS array_json_b
   FROM  (SELECT col1, col2 FROM b WHERE id = a.id) x
   ) b ON true
LEFT   JOIN LATERAL (
   SELECT json_agg(x) AS array_json_c
   FROM  (SELECT col1, col2 FROM c WHERE id = a.id) x
   ) c ON true
WHERE  id = 1;

相关:

  • Return multiple columns of the same row as JSON array of objects