gpt4 book ai didi

json - 展平来自 JSONB 字段的聚合键/值对?

转载 作者:行者123 更新时间:2023-11-29 12:24:19 24 4
gpt4 key购买 nike

我在 Postgres 9.4 中使用下表:

     Column      │         Type         │ Modifiers
─────────────────┼──────────────────────┼──────────────────────
id │ integer │ not null default
practice_id │ character varying(6) │ not null
date │ date │ not null
pct_id │ character varying(3) │
total_list_size │ double precision │ not null
star_pu │ jsonb │

我有以下查询:

SELECT date,
AVG(total_list_size) AS total_list_size,
json_object_agg(key, val) AS star_pu
FROM (SELECT date,
SUM(total_list_size) AS total_list_size,
key, SUM(value::numeric) val FROM frontend_practicelist p,
jsonb_each_text(star_pu)
GROUP BY date, key ) p
GROUP BY date
ORDER BY date;

它为我提供了附加到 star_pu 的 JSON 对象的结果:

date            │ 2013-04-01
total_list_size │ 56025123.000000000000
star_pu │ { "antidepressants_cost" : 180102416.8036909901975399, "antiepileptic_drugs_cost" : 296228344.171576079922216... }

相反,我想将 JSON 结果扁平化为一系列带命名空间的键,因此结果如下所示:

date                             │ 2013-04-01
total_list_size │ 56025123.000000000000
star_pu.antidepressants_cost │ 180102416.8036909901975399
star_pu.antiepileptic_drugs_cost │ 296228344.171576079922216
...

这可能吗?

最佳答案

这个特殊情况

下面的函数基于表动态创建 View :

create or replace function create_totals_view(table_name text)
returns void language plpgsql as $$
declare
s text;
begin
execute format ($fmt$
select string_agg(format('star_pu->>''%s'' "%s"', key, key), ',')
from (
select distinct key
from %s, json_each(star_pu)
order by 1
) s;
$fmt$, '%s', '%s', table_name)
into s;
execute format('
drop view if exists %s_view;
create view %s_view as
select date, total_list_size, %s from %s',
table_name, table_name, s, table_name);
end $$;

首先,根据您的查询创建一个表。

create table totals as

SELECT date,
AVG(total_list_size) AS total_list_size,
json_object_agg(key, val) AS star_pu
FROM (SELECT date,
SUM(total_list_size) AS total_list_size,
key, SUM(value::numeric) val FROM frontend_practicelist p,
jsonb_each_text(star_pu)
GROUP BY date, key ) p
GROUP BY date
ORDER BY date;

接下来,使用该函数,它将创建一个以 _view 后缀的表命名的 View :

select create_totals_view('totals');

最后查询 View :

select * from totals_view;

通用解决方案(jsonb)

create or replace function create_jsonb_flat_view
(table_name text, regular_columns text, json_column text)
returns text language plpgsql as $$
declare
cols text;
begin
execute format ($ex$
select string_agg(format('%2$s->>%%1$L "%%1$s"', key), ', ')
from (
select distinct key
from %1$s, jsonb_each(%2$s)
order by 1
) s;
$ex$, table_name, json_column)
into cols;
execute format($ex$
drop view if exists %1$s_view;
create view %1$s_view as
select %2$s, %3$s from %1$s
$ex$, table_name, regular_columns, cols);
return cols;
end $$;

用法:

create table example (id int, name text, params jsonb);
insert into example values
(1, 'Anna', '{"height": 175, "weight": 55}'),
(2, 'Bob', '{"age": 22, "height": 188}'),
(3, 'Cindy', '{"age": 25, "weight": 48, "pretty": true}');

select create_jsonb_flat_view('example', 'id, name', 'params');

select * from example_view;

id | name | age | height | pretty | weight
----+-------+-----+--------+--------+--------
1 | Anna | | 175 | | 55
2 | Bob | 22 | 188 | |
3 | Cindy | 25 | | true | 48
(3 rows)

关于json - 展平来自 JSONB 字段的聚合键/值对?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49268463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com