Trino: How to concatenate arrays grouped by another column in Presto?
Бывает нужно собрать размазанные по строкам массивы в один красивый массив для каждого ключа. Табличка в одну сторону, а тебе надо в другую — классика.
Бывает нужно собрать размазанные по строкам массивы в один красивый массив для каждого ключа. Табличка в одну сторону, а тебе надо в другую — классика.
Допустим, есть у тебя данные, где для одного id несколько записей, и в каждой свой массив. А тебе нужна одна строка на id и один большой массив, склеенный из всех остальных.
Простой случай: массивы из одного элемента
Если у тебя в каждой строке гарантированно массив ровно с одним элементом, то всё просто. Используй array_agg, но обращайся к элементу.
select id, array_agg(array[0])
from your_table
group by id;
Здесь array[0] просто вытаскивает первый (и, по сути, единственный) элемент из каждого массива. array_agg соберёт все эти элементы в новый массив для каждой группы id.
Реальный мир: массивы любой длины
А если в исходных данных массивы могут быть разной длины? Тогда предыдущий запрос склеит не элементы, а сами массивы как элементы. Получится массив массивов, а это скорее всего не то, что нужно.
Надо эти массивы сначала “развернуть” и склеить уже элементы. Для этого есть flatten.
select id, flatten(array_agg(array))
from your_table
group by id;
array_agg(array) соберёт все твои массивы в один массив второго порядка. А flatten берет этот массив массивов и делает из него один плоский одномерный массив, соединяя все элементы по порядку.
Что под капотом
Операция flatten — это именно то, что нужно для конкатенации. Она не меняет порядок элементов внутри исходных массивов, просто последовательно присоединяет один массив к другому.
Если в одном из исходных массивов был NULL, он будет проигнорирован. Если нужно сохранить NULL как элемент, это уже отдельная история, но в большинстве случаев такое поведение — то, что нужно.
Итог
Два запроса покрывают все сценарии. Если массивы одноэлементные — бери первый вариант, он чуть проще. Если в массивах может быть больше одного элемента или длина неизвестна — всегда используй flatten(array_agg(...)).
Всё остальное — уже особенности твоей схемы данных. Главное, что механизм склейки теперь у тебя в кармане.