Presto: агрегировать массивы для всех столбцов

#sql #arrays #distinct #presto #trino

#sql #массивы #distinct #presto #trino

Вопрос:

У меня есть следующая таблица:

 name   pets
Alex   [dog, cat, bird]
Tom    [rabbit, cat]
Mary   [snake, dog, fish, cow]
Dave   [dog]
  

Мне интересно, можно ли создать запрос для поиска всех домашних животных. То есть я ищу вывод, подобный:

 [dog, cat, bird, rabbit, snake, fish, cow]
  

Текущие подходы — экспортировать таблицу в csv и использовать python для ее решения. Мне интересно, можно ли это сделать непосредственно в запросе Presto? Спасибо!

Ответ №1:

Presto обладает мощными функциями массива. Это должно сработать:

 select array_distinct(flatten(array_agg(pets))) all_pets
from mytable
  

В основном это объединяет все массивы в виде массива массивов, затем объединяет все элементы в один массив и, наконец, удаляет дубликаты.

Ответ №2:

Расширяя ответ @GMB, это может быть более удобным с точки зрения масштабируемости:

 presto> SELECT array_agg(DISTINCT e)
     -> FROM (VALUES ARRAY[1,2,3], ARRAY[2,3,4]) t(a)
     -> CROSS JOIN UNNEST(a) AS u(e);
    _col0
--------------
 [3, 2, 4, 1]
  

Это определенно более подробная версия array_distinct(flatten(array_agg(pets))) , но позволяет избежать создания экземпляра массива или массивов в памяти.

(В идеале оптимизатор Presto должен иметь возможность преобразовывать одно в другое, но пока это не так.)