Postgresql - сопоставить массив массивов в один массив в определенном порядке - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть таблица PostgreSQL, содержащая столбец данных одномерного массива. Для выполнения совокупного запроса по этому столбцу я буду sh, получая минимальное / максимальное / среднее для каждого элемента массива, а также счетчик групп, возвращая результат в виде одномерного массива. Длины массивов в таблице могут различаться, но я могу быть уверен, что в любой выполняемой группировке все массивы будут одинаковой длины.

В простой форме, скажем, мои массивы имеют длину 2 и имеют показания для х и у, я хочу вернуть результат в виде {Мин (х), Макс (х), Среднее (х), Мин (у), Макс (у), Среднее (у), Количество ()}

Я могу получить результат в виде {Мин (х), Мин (х), Макс (х), Макс (у), Среднее (х), Среднее (y) Count ()}, но я не могу оттуда получить желаемый результат.

Вот пример, показывающий, где я нахожусь (на этот раз с массивами длины 3, но без означает агрегацию, так как ее нет для массивов, встроенных в pg Sql): ( SQLFiddle здесь )

CREATE TABLE my_test(some_key numeric, event_data bigint[]);

INSERT INTO my_test(some_key, event_data) VALUES
(1, {11,12,13}),
(1, {5,6,7}),
(1, {-11,-12,-13});

SELECT MIN(event_data) || MAX(event_data) || COUNT(event_data)  FROM my_test GROUP BY some_key;

Приведенное выше дает мне

{ 11,12,13, -11, -12, -13,3}

Однако я не знаю, как преобразовать результат, подобный приведенному выше, в то, что я хочу, а именно:

{11, -11,12, -12,13, -13,3}

Какую функцию я должен использовать для преобразования ove?

Обратите внимание, что перечисленные выше функции агрегирования не совсем совпадают с теми, которые я использую, чтобы получить min, max - я использую расширение aggs_for_vecs , чтобы дать мне min, max и имею в виду.

1 Ответ

0 голосов
/ 14 февраля 2020

Я бы порекомендовал использовать операции с массивами и агрегацию:

select x.some_key,
       array_agg(u.val order by x.n, u.nn)
from (select t.some_key, ed.n, min(val) as minval, max(val) as maxval
      from my_test t cross join lateral
           unnest(t.event_data) with ordinality as ed(val, n)
      group by t.some_key, ed.n
     ) x cross join lateral
     unnest(array[x.minval, x.maxval]) with ordinality u(val, nn)
group by x.some_key;

Лично я бы предпочел массив с тремя элементами и мин / макс в качестве записи:

select x.some_key, array_agg((x.minval, x.maxval) order by x.n)
from (select t.some_key, ed.n, min(val) as minval, max(val) as maxval
      from my_test t cross join lateral
           unnest(t.event_data) with ordinality as ed(val, n)
      group by t.some_key, ed.n
     ) x 
group by x.some_key;

Здесь - это дБ <> скрипка.

...