Errors
Trino

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 твой лучший друг для таких задач.