【问题标题】:Count freuency of array or jsonb object数组或json对象的计数频率
【发布时间】:2021-04-23 09:01:45
【问题描述】:

在pg中,有一个varchar类型的标签字段,包含由]分隔的标签,例如'a]b]c'

需要计算这些标签在多行中出现的次数。

我知道如何:

  • 将原始字符串转换为pg数组['a', 'b', 'c']
  • 如果该列以 jsonb 对象{'a':1, 'b':1, 'c':1} 的形式给出,则可以通过 jsonb 函数计算频率。

但是我不知道如何将pg数组['a', 'b', 'c']转换为jsonb对象{'a':1, 'b':1, 'c':1},或者直接计算数组元素的频率。

问题是:

  • A.如何将文本'a]b]c'转换成jsonb对象{'a':1, 'b':1, 'c':1},所有值都为1
  • 乙。如何计算数组元素 ['a', 'b', 'c'] 跨多行的频率。

如果这两个问题中的任何一个都可以解决,那么原来的问题就可以解决。
或者,还有更好的解决方案?


@Update - 让问题更清楚

如果输入列已经是 json 对象,而不是原始字符串或数组。

下表显示了我想要做什么:

-- create table,
create table json_aggr_learn (
    id serial8 primary key,
    uid int8,
    freq jsonb,
    created_at timestamptz default current_timestamp
);

-- init data
insert into json_aggr_learn(uid, freq) values
(1, '{"a":1, "b":2}'),
(1,'{"b":2, "c":4}'),
(2, '{"a":1, "b":2}'),
(2,'{"b":7, "c":4}'),
(2,'{"e":10, "c":4}'),
(3,'{"a":5, "c":4, "f":2}');

select * from json_aggr_learn limit 5;

-- aggr
select uid, jsonb_object_agg(key, value) as merged_freq
from
     (select id, uid, key, value
      from json_aggr_learn, jsonb_each_text(freq)
     ) as expended
group by uid
order by uid;

这里是 aggr sql 的输出:

【问题讨论】:

  • 您能否解释一下如何计算多行数组元素 ['a', 'b', 'c'] 的频率。例如,如果有 2 行,其中 row-1-col-1 = ['a','b','a'] 和 row-2-col1 = ['c', 'a', 'b']您期望的行/列输出是多少?
  • @praxnet 预期的输出是{'a':2,'b':2,'c':2},元素的顺序无关紧要。我已经用更多信息更新了这个问题。

标签: postgresql jsonb


【解决方案1】:

你可以unnest()数组,例如:

select id, jsonb_object_agg(tag, count) as tags
from (
    select id, unnest(string_to_array(tags, ']')) as tag, count(*)
    from my_table
    group by 1, 2
    ) s
group by 1
order by 1

Db<>fiddle.

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2016-08-24
  • 1970-01-01
相关资源
最近更新 更多