不幸的是,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.使用子选择
使用subselect构造派生表并整体引用该表。这也带有列名。它比较冗长,但是您不需要注册类型:
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;
SELECT a.id, a.name
, json_agg(json_build_object('col1', b.col1, 'col2', b.col2, 'col3', b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
有关:
与jsonb
各自的功能jsonb_agg()
和相似jsonb_build_object()
。
对于Postgres的9.5或更高版本还看到a_horse的回答用新的更短的语法变种:Postgres的加减运算-
的jsonb
说“这只是一个键的所有键”。
由于Postgres 10的 “除几个键外”是使用与text[]
第二个操作数相同的运算符实现的-如mlt注释。