我想将兄弟记录中的一些数据聚合到一个jsonb字段中。
以下是一个示例数据结构,与我正在使用的数据结构非常相似:
CREATE TABLE so.a (
id integer,
foo integer,
bar integer,
-- a lot of other data
CONSTRAINT a_pkey PRIMARY KEY (id)
);
CREATE TABLE so.b (
id integer,
a1 integer,
a2 integer,
data jsonb,
CONSTRAINT b_pkey PRIMARY KEY (id),
CONSTRAINT "a1_fkey" FOREIGN KEY (a1) REFERENCES so.a (id),
CONSTRAINT "a2_fkey" FOREIGN KEY (a2) REFERENCES so.a (id)
);
和一些示例数据集:
INSERT INTO so.a VALUES
(1, 42, 24),
(2, 22, 33),
(3, 66, 99);
INSERT INTO so.b VALUES
(1, 1, 2, NULL),
(2, 2, 3, NULL),
(3, 3, 1, NULL);
现在,我想在b.data
行填充来自兄弟记录a1
和a2
的数据:
data = [{
"foo": a1.foo,
"bar": a1.bar
}, {
"foo": a2.foo,
"bar": a2.bar
}]
我提出的最佳解决方案是首先使用json
函数和字符串连接运算符to_json
构建||
字符串,然后再将其转换为jsonb
:< / p>
UPDATE
so.b
SET
data = ('[{
"foo": ' || to_json(t1.foo) || ',
"bar": ' || to_json(t1.bar) || '
}, {
"foo": ' || to_json(t2.foo) || ',
"bar": ' || to_json(t2.bar) || '
}]')::jsonb
FROM
so.a t1,
so.a t2
WHERE
t1.id = b.a1 AND
t2.id = b.a2;
此解决方案非常有效:
SELECT id, data FROM so.b;
-- 1, [{"bar": 24, "foo": 42}, {"bar": 33, "foo": 22}]
-- 2, [{"bar": 33, "foo": 22}, {"bar": 99, "foo": 66}]
-- 3, [{"bar": 99, "foo": 66}, {"bar": 24, "foo": 42}]
但对我来说似乎太笨拙了。
所以我想知道,也许有更好的方法来实现我想要的目标。
UPD。:如果我还要描述我之前解决此问题的尝试,我认为这可能会有所帮助。
我想保持简单,所以我尝试使用array_to_json
功能:
SET
data = array_to_json(ARRAY[t1, t2])
但我的数据库中有很多过多的数据。由于我无法找到限制t1
和t2
字段的方法,因此我放弃了这种方法。
答案 0 :(得分:1)
我认为你唯一能做的就是使用jsonb_build_*
函数而不是字符串连接。我:
UPDATE so.b SET
data = jsonb_build_array(
jsonb_build_object(
'foo', to_json(t1.foo),
'bar', to_json(t1.bar)
),
jsonb_build_object(
'foo', to_json(t2.foo),
'bar', to_json(t2.bar)
)
)
FROM
so.a t1, so.a t2
WHERE
t1.id = b.a1 AND t2.id = b.a2;