SQL запрос с преобразованием данных для Sankey диаграммы
Прошу помочь с решением задачи. По SQL запросу из Grafana в Postgres получаю следующие тестовые данные (уже отсортированы по времени)
s_id |p_value|
id_1 |val_1 |
id_1 |val_2 |
id_2 |val_1 |
id_3 |val_1 |
id_3 |val_2 |
id_3 |val_3 |
id_3 |val_4 |
Требуется преобразовать эти данные для диаграммы Sankey, получив три столбца - "scr", "dst", "count". Т.е. сначала в рамках уникального id получить точки перехода и потом просуммировать уникальные пары.
Например,
для id_1 есть два значения. Получается одна пара: val_1, val_2
для id_2 всего одно значение. Тут получить пару val_1, 'Заглушка'
для id_3 четыре значения. Тут получить пары val_1, val_2 val_2, val_3 val_3, val_4 (получается у каждого последующего значения в качестве входа предыдущее значение)
И далее эти уникальные пары просуммировать и получить их количество. Можно ли это сделать в рамках SQL запроса более сложного, или эффективнее будет адаптировать данные внутри Grafana?
Исходный запрос был такой: select s_id, p_value from params where param_name = 'Project' and (changed >= '2025-04-01' and changed <= '2025-04-05') order by changed;
UPDATE Ничего умнее на моем уровне понимания SQL не придумал, но код ниже работает. В любом случае буду рад совету по оптимизации запроса, тут совсем нет анализа глубины переходов в массиве и тп
with
allProjectsCalls as (
select s_id, array_agg(p_value order by changed) as projects
from params
where param_name = 'ProjectId' and changed >= '2025-04-02 00:00:00.000' and changed <= '2025-04-02 23:59:59.999'
group by s_id
),
arrayUpper as (
select session_id, array_upper(projects, 1) as arrayUpper, projects
from allProjectsCalls -- Это задел на анализ глубины массива
),
pair as (
select unnest(projects[1:1]) as src, unnest(projects[2:2]) as dst from arrayUpper
union all
select unnest(projects[2:2]) as src, unnest(projects[3:3]) as dst from arrayUpper
union all
select unnest(projects[3:3]) as src, unnest(projects[4:4]) as dst from arrayUpper
union all
select unnest(projects[4:4]) as src, unnest(projects[5:5]) as dst from arrayUpper
union all
select unnest(projects[5:5]) as src, unnest(projects[6:6]) as dst from arrayUpper
union all
select unnest(projects[6:6]) as src, unnest(projects[7:7]) as dst from arrayUpper
union all
select unnest(projects[7:7]) as src, unnest(projects[8:8]) as dst from arrayUpper
union all
select unnest(projects[8:8]) as src, unnest(projects[9:9]) as dst from arrayUpper
)
select src, dst, count (*) from pair group by src, dst