Postgres сплющил ячейку JSONB в строку зрения - PullRequest
0 голосов
/ 21 января 2019

У меня есть простая таблица postgres:

    Column    │         Type         │ Modifiers
──────────────┼──────────────────────┼──────────────────────
 id           │ integer              │ not null default
 data         │ jsonb                │

Вот упрощенная структура данных для data:

{
  "id": 3,
  "date": "2019-01-01",
  "well_report_table":
    [
      {"element": "methane",
      "yield": 6,
      "price": 2.10
      },
      {"element": "pentane",
      "yield": 6,
      "price": 2.10
      },
      {"element": "butane",
      "yield": 6,
      "price": 3.50
      }
    ],
  "cost_report_table":
    [
      {"item": "fuel",
      "charge": 6.30
      },
      {"item": "lease",
      "charge": 200
      }
    ]
}

Я хотел бы сгладить это в представлении сследующие столбцы:

id | date | well_report_table_methane_yield | well_report_table_methane_price | well_report_table_pentane_yield | well_report_table_pentane_price | well_report_table_butane_yield | well_report_table_butane_price |cost_report_table_fuel_charge | cost_report_table_lease_charge

У объектов в моих массивах есть идентификатор, который я хотел бы добавить к имени объекта массива, а затем перебрать другие ключи в объекте и сделать столбцы из .

Этот вопрос мне подходит: Postgres: Сгладить агрегированные пары ключ / значение из поля JSONB?

Я не совсем уверен, что это возможно вчто-то вроде plpgsql, так что если мне просто нужно сгенерировать текст представления на языке сценариев, таком как ruby ​​/ python, а затем создать представление из этого, я согласен с этим.

В идеале я будув состоянии использовать что-то вроде jsonb_array_elements и jsonb_each, чтобы избежать промежуточных таблиц (все мои текущие попытки требуют промежуточных представлений), но я еще не нашел эту магическую комбинацию.

1 Ответ

0 голосов
/ 21 января 2019

Это не общий вопрос о выравнивании массивов JSON, потому что в массивах скрыта особая логика.Вы можете реализовать логику в этой функции:

create or replace function flat_array(data jsonb, title text, item text)
returns jsonb language sql immutable as $$
    select jsonb_object_agg(format('%s_%s_%s', title, elem->>item, key), value)
    from jsonb_array_elements(data->title) as arr(elem)
    cross join jsonb_each(elem)
    where key <> item
$$;

Запрос:

select 
    jsonb_build_object('id', data->'id', 'date', data->'date') ||
    flat_array(data, 'well_report_table', 'element') ||
    flat_array(data, 'cost_report_table', 'item')
from my_table

дает объект:

{
    "id": 3,
    "date": "2019-01-01",
    "cost_report_table_fuel_charge": 6.30,
    "cost_report_table_lease_charge": 200,
    "well_report_table_butane_price": 3.50,
    "well_report_table_butane_yield": 6,
    "well_report_table_methane_price": 2.10,
    "well_report_table_methane_yield": 6,
    "well_report_table_pentane_price": 2.10,
    "well_report_table_pentane_yield": 6
}

, который может быть преобразован в табличныйпосмотреть способом, описанным в Свести агрегированные пары ключ / значение из поля JSONB?

...