我正在努力对 PostgreSQL 数据库中的 JSONB 字段进行聚合。这可能更容易用一个例子来解释,所以如果创建并填充一个名为analysis
2 列 (id
和analysis
) 的表,如下所示:-
create table analysis (
id serial primary key,
analysis jsonb
);
insert into analysis
(id, analysis) values
(1, '{"category" : "news", "results" : [1, 2, 3, 4, 5 , 6, 7, 8, 9, 10, 11, 12, 13, 14, null, null]}'),
(2, '{"category" : "news", "results" : [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, null, 26]}'),
(3, '{"category" : "news", "results" : [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46]}'),
(4, '{"category" : "sport", "results" : [51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66]}'),
(5, '{"category" : "sport", "results" : [71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86]}'),
(6, '{"category" : "weather", "results" : [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106]}');
如您所见,analysis
JSONB 字段始终包含 2 个属性category
和results
. results 属性将始终包含一个大小为 16 的固定长度数组。我使用了各种函数,例如,jsonb_array_elements
但我想要做的是以下内容: -
- 按分析分组->“类别”
- 每个数组元素的平均值
当我想要一个语句返回按类别(即news
,sport
和weather
)分组的 3 行和一个包含平均值的 16 个固定长度数组时。更复杂的是,如果数组中有null
s,那么我们应该忽略它们(即我们不是简单地按行数求和和平均)。结果应如下所示:-
category | analysis_average
-----------+--------------------------------------------------------------------------------------------------------------
"news" | [14.33, 15.33, 16.33, 17.33, 18.33, 19.33, 20.33, 21.33, 22.33, 23.33, 24.33, 25.33, 26.33, 27.33, 45, 36]
"sport" | [61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76]
"weather" | [91, 92, 93, 94, 95, 96, 97, 98, 99, 00, 101, 102, 103, 104, 105, 106]
注意:请注意第一行最后 2 个数组项中的45
and说明忽略s。36
nulls
我曾考虑创建一个视图,将数组分解为 16 列,即
create view analysis_view as
select a.*,
(a.analysis->'results'->>0)::int as result0,
(a.analysis->'results'->>1)::int as result1
/* ... etc for all 16 array entries .. */
from analysis a;
这对我来说似乎非常不雅,并且首先消除了使用数组的优势,但可能会使用这种方法将某些东西组合在一起。
任何指示或提示将不胜感激!
性能在这里也很重要,所以性能越高越好!