Select table 作为 json 数组
Select table as json array
我在 PostgreSQL 中有三个 table:A
、B
、C
。
我想从 table A
中获取具有特定 id
的行,以及来自 table 的 B
和 C
中匹配 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 在 b
或 c
中找不到匹配项, returns 而是一个空数组。可能重要也可能不重要。
实际答案
问题中的示例从结果中排除了 b
和 c
中多余的 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 选择使用子选择(本例中为 col1
和 col2
):
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
我在 PostgreSQL 中有三个 table:A
、B
、C
。
我想从 table A
中获取具有特定 id
的行,以及来自 table 的 B
和 C
中匹配 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 在 b
或 c
中找不到匹配项,
实际答案
问题中的示例从结果中排除了 b
和 c
中多余的 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 选择使用子选择(本例中为 col1
和 col2
):
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