Я попытаюсь представить текущую настройку в виде абстрактного представления, фокусируясь на логическом подходе к пакетной вставке.
CREATE TABLE factv (id, ..other columns..);
CREATE TABLE facto (id, ..other columns..);
CREATE TABLE dims (id serial, dimensions jsonb);
2 таблицы фактов имеют одинаковые измерения, но у них естьразные столбцы.
Есть поток событий, который отправляет сообщения в таблицу, и есть функция, которая выполняется для каждой строки, логика похожа на:
CREATE OR REPLACE FUNCTION insert_event() RETURNS TRIGGER AS $$
IF event_json ->> 'type' = 'someEvent' THEN
WITH factv_insert AS (
INSERT INTO factv VALUES (id,..other columns..)
fn_createDimId,
NEW.event_json->>..,
...
RETURNING id
)
INSERT INTO facto VALUES (id,..other columns..)
(select id from factv_insert),
NEW.event_json->>..
ELSE DoSomethingElse...
END IF;
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
Функция, вызываемая здесь fn_createDimId
просто просматривает таблицу dims
и, если эти измерения не найдены, они вставляются. Если они уже есть, просто дайте мне этот идентификатор для этих измерений в качестве идентификатора для вставки этого факта.
У меня действительно есть несколько новых событий, и мне нужно получить некоторую информацию, которая нарушает правила вставкив ... значения с ERROR: more than one row returned by a subquery used as an expression
Структура события аналогична, но не ограничивается
{
"type": "someEvent",
"instruction": {
"contains": {
"id": "containerid",
"map": {
"50561:null:null": {
"productid": "50561",
"quantity": 3
},
"50562:null:null": {
"productid": "50562",
"quantity": 8
},
"50559:null:null": {
"productid": "50559",
"quantity": 5
}
}
},
"target": {
"50561": "Random",
"50562": "Random",
"50559": "Mix",
}
}
}
Здесь возникают проблемы с информацией вокруг target
и соответствующими величинамидля этих идентификаторов. Из события, показанного выше, мне нужно объединить и вставить в таблицу фактов:
-------|-----
target | qty
-------|-----
Random | 11
Mixed | 5
-------------
Если бы мне нужно было запросить информацию, я бы запустил следующее:
WITH meta_data as (
SELECT
json_object_keys(event_json -> 'instruction' ->'target') as prodid
,event_json -> 'instruction' ->'target'->>json_object_keys(event_json -> 'instruction' ->'target') as target
,event_json -> 'instruction' ->'contains'->'map'->json_object_keys(event_json -> 'instruction' ->'contains'->'map')->>'quantity' as qty
FROM event_table )
select
target,
sum(qty::int)
from meta_data
group by target;
Я ищу решение, которое позволяет выполнять те же логические операции, но преодолевает ошибку в нескольких возвращаемых строках, в идеале - итерацию для каждого события, которое возвращает более 1 строки.