PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Изравняване на агрегираните двойки ключ/стойност от JSONB поле?

Този конкретен случай

Функцията по-долу динамично създава изглед въз основа на таблица:

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 постфикс:

select create_totals_view('totals');

Накрая потърсете изгледа:

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)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проблеми при настройката на персонализиран първичен ключ при миграция на Rails 4

  2. Как да предадете масив от персонализиран тип на функцията Postgres

  3. Как да получите първи и последен запис от sql заявка?

  4. Изпълнете динамична кръстосана заявка

  5. COPY с динамично име на файл