转换为JSON时如何使用行列的子集?

How to use a subset of the row columns when converting to JSON?

我有一个 table t,其中包含一些列 abc。我使用以下查询将行转换为 JSON 对象数组:

SELECT COALESCE(JSON_AGG(t ORDER BY c), '[]'::json)
FROM   t

这 returns 符合预期:

[
  {
    "a": ...,
    "b": ...,
    "c": ...
  },
  {
    "a": ...,
    "b": ...,
    "c": ...
  }
]

现在我想要相同的结果,但输出中只有 ab 列。我仍将使用列 c 进行排序。我想到的最好的如下:

SELECT COALESCE(JSON_AGG(JSON_BUILD_OBJECT('a', a, 'b', b) ORDER BY c), '[]'::json)
FROM   t

[
  {
    "a": ...,
    "b": ...
  },
  {
    "a": ...,
    "b": ...
  }
]

虽然这很好用,但我想知道是否有更优雅的方法来做到这一点。令我沮丧的是我必须手动定义 JSON 属性。当然,我知道我必须枚举 ab 列,但奇怪的是我必须 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