SELECT a.id, a.name, json_agg(b.*) as "item"
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
如何选择
b
中的列,以便在JSON对象中没有b.item_id
? >我已经阅读过ROW
,但是它返回了一个JSON对象,例如: 。我想避免这种情况,并保留原始列名称。#1 楼
不幸的是,SQL语法中没有规定说“除这一列外的所有列”。您可以通过在行类型表达式中拼写剩余的列列表来实现目标:SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
这是更明确的形式的缩写:
ROW
(b.col1, b.col2, b.col3)
。保存在行类型表达式中。您可以通过这种方式在JSON对象中获得通用键名称。我看到3个保留原始列名的选项:1。强制转换为注册类型
强制转换为已知(注册)行类型。为每个现有表或视图或使用显式
CREATE TYPE
语句注册类型。您可以将临时表用于临时解决方案(在会话期间有效):CREATE TEMP TABLE x (col1 int, col2 text, col3 date); -- use adequate data types!
SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)::x) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
2。使用子选择
使用子选择来构造派生表并整体引用该表。这也带有列名。它比较冗长,但是您不需要注册类型:
SELECT a.id, a.name
, json_agg((SELECT x FROM (SELECT b.col1, b.col2, b.col3) AS x)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
json_build_object()
相关信息:
以SQL(Postgres)中的JSON对象数组形式返回函数
jsonb
和jsonb_agg()
。对于Postgres 9.5或更高版本,还请参见a_horse的答案,其中包含一个新的较短语法变体:Postgres为
jsonb_build_object()
添加了负运算符-
表示“除此键之外的所有键”。使用相同的运算符将jsonb
作为第二个操作数来实现10个“除几个键外”-像mlt一样。#2 楼
从9.6开始,您可以简单地使用-
从JSONB中删除密钥:然后将其结果汇总。评论
这项新功能似乎是OP所希望的。我在答案中添加了链接。
–欧文·布兰德斯特(Erwin Brandstetter)
18-3-14在15:06
当我尝试subselect变体时,出现与json_agg函数相关的错误:函数json_agg(record)不存在
–夹具
18年8月13日在0:01
@fraxture:则您没有使用Postgres 9.6
– a_horse_with_no_name
18年8月13日在10:06
确实,这就是问题所在。 v9.2中有什么方法可以过滤列?
–夹具
18年8月13日在13:51
#3 楼
实际上,您可以使用子查询而无需分组来实现出席真的很有趣,并且有更多详细信息
#4 楼
您可以像这样使用json_build_object
SELECT
a.id,
a.name,
json_agg(json_build_object('col1', b.col1, 'col2', b.col2) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
#5 楼
我发现最好创建JSON,然后对其进行聚合。例如,with base as (
select a, b, ('{"ecks":"' || to_json(x) || '","wai":"' || to_json(y) || '","zee":"' || to_json(z) || '"}"')::json c
) select (a, b, array_to_json(array_agg(c)) as c)
注意,如果您不喜欢CTE(或者由于使用CTE而导致性能问题),则可以将其作为子查询来完成。
还要注意,如果您打算做很多事情,创建一个函数来包装键-值对可能会比较有益,这样代码看起来会更干净。您将传递函数(例如)
'ecks', 'x'
,并返回"ecks": "x"
。#6 楼
尽管除了选择一位之外,仍然没有办法对所有列进行任何选择,但是您可以使用json_agg(to_json(b.col_1, b.col_2, b.col_3 ...))
以{"col_1":"col_1 value", ...}
的格式获取json的json数组。 ,因此查询将类似于:
/>
(我现在使用的是Postgres 9.5.3,不确定何时添加此支持。)
评论
这不起作用(至少在最新版本中); to_json()不可变。
–墨水
20-10-28在6:01
评论
>或几个键请注意,json(b)-text []从10开始可用。
– mlt
18年8月7日在21:25
解决方案3对我来说就像是魅力!
–路易斯·费尔南多·达席尔瓦(Luiz Fernando da Silva)
19年8月20日在18:11
Postgres 9.2版中功能json_build_object()的替代方法?
–阿贾伊·塔库尔(Ajay Takur)
20年9月2日,12:10