转换为JSON时如何使用行列的子集?
How to use a subset of the row columns when converting to JSON?
我有一个 table t
,其中包含一些列 a
、b
和 c
。我使用以下查询将行转换为 JSON 对象数组:
SELECT COALESCE(JSON_AGG(t ORDER BY c), '[]'::json)
FROM t
这 returns 符合预期:
[
{
"a": ...,
"b": ...,
"c": ...
},
{
"a": ...,
"b": ...,
"c": ...
}
]
现在我想要相同的结果,但输出中只有 a
和 b
列。我仍将使用列 c
进行排序。我想到的最好的如下:
SELECT COALESCE(JSON_AGG(JSON_BUILD_OBJECT('a', a, 'b', b) ORDER BY c), '[]'::json)
FROM t
[
{
"a": ...,
"b": ...
},
{
"a": ...,
"b": ...
}
]
虽然这很好用,但我想知道是否有更优雅的方法来做到这一点。令我沮丧的是我必须手动定义 JSON 属性。当然,我知道我必须枚举 a
和 b
列,但奇怪的是我必须 copy/paste 对应的 JSON 属性 名称,这与列名完全相同。
还有其他方法吗?
您可以使用 row_to_json 而不是手动构建对象:
CREATE TABLE foobar (a text, b text, c text);
INSERT INTO foobar VALUES
('1', 'LOREM', 'A'),
('2', 'LOREM', 'B'),
('3', 'LOREM', 'C');
--Using CTE
WITH tmp AS (
SELECT a, b FROM foobar ORDER BY c
)
SELECT json_agg(row_to_json(t)) FROM tmp t
--Using subquery
SELECT
json_agg(row_to_json(t))
FROM
(SELECT a, b FROM foobar ORDER BY c) t;
编辑: 正如您所说,结果顺序是一个严格的要求。在这种情况下,您可以使用行构造函数来构建 json 对象:
--Using a type to build json with desired keys
CREATE TYPE mytype AS (a text, b text);
SELECT
json_agg(
to_json(
CAST(
ROW(a, b) AS mytype
)
)
ORDER BY c)
FROM
foobar;
--Ignoring column names...
SELECT
json_agg(
to_json(
ROW(a, b)
)
ORDER BY c)
FROM
foobar;
SQL Fiddle here.
在子查询或 cte 中执行排序,然后应用 json_agg
SELECT COALESCE(JSON_AGG(t2), '[]'::json)
FROM (SELECT a, b FROM t ORDER BY c) t2
或者使用 jsonb。 jsonb 类型允许通过指定它们的键来删除项目
SELECT coalesce(jsonb_agg(row_to_json(t)::jsonb - 'c'
order by c), '[]'::jsonb)
FROM t
我有一个 table t
,其中包含一些列 a
、b
和 c
。我使用以下查询将行转换为 JSON 对象数组:
SELECT COALESCE(JSON_AGG(t ORDER BY c), '[]'::json)
FROM t
这 returns 符合预期:
[
{
"a": ...,
"b": ...,
"c": ...
},
{
"a": ...,
"b": ...,
"c": ...
}
]
现在我想要相同的结果,但输出中只有 a
和 b
列。我仍将使用列 c
进行排序。我想到的最好的如下:
SELECT COALESCE(JSON_AGG(JSON_BUILD_OBJECT('a', a, 'b', b) ORDER BY c), '[]'::json)
FROM t
[
{
"a": ...,
"b": ...
},
{
"a": ...,
"b": ...
}
]
虽然这很好用,但我想知道是否有更优雅的方法来做到这一点。令我沮丧的是我必须手动定义 JSON 属性。当然,我知道我必须枚举 a
和 b
列,但奇怪的是我必须 copy/paste 对应的 JSON 属性 名称,这与列名完全相同。
还有其他方法吗?
您可以使用 row_to_json 而不是手动构建对象:
CREATE TABLE foobar (a text, b text, c text);
INSERT INTO foobar VALUES
('1', 'LOREM', 'A'),
('2', 'LOREM', 'B'),
('3', 'LOREM', 'C');
--Using CTE
WITH tmp AS (
SELECT a, b FROM foobar ORDER BY c
)
SELECT json_agg(row_to_json(t)) FROM tmp t
--Using subquery
SELECT
json_agg(row_to_json(t))
FROM
(SELECT a, b FROM foobar ORDER BY c) t;
编辑: 正如您所说,结果顺序是一个严格的要求。在这种情况下,您可以使用行构造函数来构建 json 对象:
--Using a type to build json with desired keys
CREATE TYPE mytype AS (a text, b text);
SELECT
json_agg(
to_json(
CAST(
ROW(a, b) AS mytype
)
)
ORDER BY c)
FROM
foobar;
--Ignoring column names...
SELECT
json_agg(
to_json(
ROW(a, b)
)
ORDER BY c)
FROM
foobar;
SQL Fiddle here.
在子查询或 cte 中执行排序,然后应用 json_agg
SELECT COALESCE(JSON_AGG(t2), '[]'::json)
FROM (SELECT a, b FROM t ORDER BY c) t2
或者使用 jsonb。 jsonb 类型允许通过指定它们的键来删除项目
SELECT coalesce(jsonb_agg(row_to_json(t)::jsonb - 'c'
order by c), '[]'::jsonb)
FROM t