Sql 转换为JSON时如何使用行列的子集?
我有一个表Sql 转换为JSON时如何使用行列的子集?,sql,json,postgresql,jsonb,postgresql-json,Sql,Json,Postgresql,Jsonb,Postgresql Json,我有一个表t,其中有一些列a、b和c。我使用以下查询将行转换为对象的JSON数组: SELECT COALESCE(JSON_AGG(t ORDER BY c), '[]'::json) FROM t 这将如预期的那样返回: [ { "a": ..., "b": ..., "c": ... }, { "a": ..., "b": ..., "c": ... } ] 现在我想要相同的结果,但是在输出中只有列a和b。我仍将使用列
t
,其中有一些列a
、b
和c
。我使用以下查询将行转换为对象的JSON数组:
SELECT COALESCE(JSON_AGG(t ORDER BY c), '[]'::json)
FROM t
这将如预期的那样返回:
[
{
"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
,但奇怪的是,我必须复制/粘贴相应的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 FIDLE。在子查询或cte中执行排序,然后应用
json\u 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
但这不包括列
c
上的排序。在CTEtmp
或子查询中简单地按c添加ORDER是不正确的,因为您需要在外部查询中进行排序。因此,您需要将c
添加到CTE或子查询中的投影中。但接下来你又回到了原来的问题……为什么在外部查询中需要排序?请看这里:在这种情况下,“异常”是因为LIMIT子句。我不是SQL专家,但我始终理解,子查询/CTE的排序不能保证按照SQL规范保留在外部查询中。我认为这是不对的。据我所知,orderby
必须在外部查询中完成。您能否给我一个反例,其中此查询会向您返回不同的结果。我尝试了以下测试数据,得到了完全相同的结果:我不是SQL专家,但我始终理解,子查询/CTE的顺序不能保证按照SQL规范保存在外部查询中。因此,从即席小提琴中衍生行为是危险的/棘手的。请参阅更新的答案,了解不依赖子查询顺序的替代解决方案这是一种创造性的构造!但我不认为这是一个理想的解决方案。