Trino: Combine rows into a list in PrestoSQL
Ты разбираешь лог, видишь одни и те же `id1` и `id2` в разных строках, а `action` каждый раз новый. И думаешь: «Ну сколько можно плодить сущности? Давайте уже в
Ты разбираешь лог, видишь одни и те же id1 и id2 в разных строках, а action каждый раз новый. И думаешь: «Ну сколько можно плодить сущности? Давайте уже всё в кучу». Хочется свернуть это в аккуратный список действий по каждому уникальному сочетанию ключей.
Было так:
id1 | id2 | actions
---------------------------
"a1" "a2" "action1"
"b1" "b2" "action2"
"a1" "a2" "action3"
А надо чтобы было так:
id1 | id2 | actions
---------------------------
"a1" "a2" ["action1", "action3"]
"b1" "b2" ["action2"]
Задача классическая — агрегация. В голове сразу всплывает GROUP BY. И это правильный путь.
Группируем и собираем
Всё решение строится на двух китах: GROUP BY и агрегирующей функции. Нужно сгруппировать строки по полям id1 и id2. А затем для каждой получившейся группы собрать значения из колонки actions в одну структуру.
В Presto/Trino для этого есть функция ARRAY_AGG. Она делает ровно что нам нужно — принимает значения и возвращает массив.
Базовый запрос будет выглядеть так:
SELECT
id1,
id2,
ARRAY_AGG(actions) AS actions
FROM your_table
GROUP BY id1, id2
Это оно. Запрос сгруппирует все строки с одинаковой парой (id1, id2) и соберёт все их actions в массив. Для пары, которая встречалась один раз, массив будет состоять из одного элемента.
Важный нюанс про строки и массивы
В исходных данных был пример с ARRAY_JOIN. Он создаёт не массив, а строку, где значения склеены через разделитель. Это другой тип данных и, скорее всего, не то что нужно. ARRAY_AGG даёт именно массив (array(varchar)), который можно потом использовать в других функциях Presto.
Если же вдруг понадобится строка, то ARRAY_JOIN(ARRAY_AGG(actions), ',') — это правильный путь. Но в вопросе явно указан ожидаемый вывод в виде списка.
Что насчёт уникальности?
ARRAY_AGG собирает все значения, включая возможные дубликаты внутри одной группы. Если в данных для одной пары id1, id2 действие "action1" повторяется дважды, оно дважды попадёт в результирующий массив.
Если это нежелательно, используй SET_AGG или оберни ARRAY_AGG в функцию ARRAY_DISTINCT:
SELECT
id1,
id2,
ARRAY_DISTINCT(ARRAY_AGG(actions)) AS actions
FROM your_table
GROUP BY id1, id2
Итог всегда один: когда нужно свернуть строки в структуру по ключам — думай GROUP BY и агрегатные функции. ARRAY_AGG в Presto твой лучший друг для таких задач.