#sql #arrays #google-bigquery #sum #aggregate-functions
# #sql #массивы #google-bigquery #сумма #агрегатные функции
Вопрос:
В BigQquery как я могу агрегировать массивы по элементам?
Например, если у меня есть эта таблица
ID | array_value |
---|---|
1 | [1, 2, 3] |
2 | [4, 5, 6] |
3 | [7, 8, 9] |
Я хочу суммировать все векторные элементы и выводить [1 4 7, 2 5 8, 3 6 9] = [12, 15, 18]
Я могу СУММИРОВАТЬ поля с плавающей SELECT SUM(float_field) FROM table
запятой с помощью, но когда я пытаюсь применить СУММУ к массиву, я получаю
Нет совпадающей подписи для агрегатной функции SUM для типов аргументов: ARRAY. Поддерживаемые подписи: SUM(INT64); SUM(FLOAT64); SUM(ЧИСЛОВОЙ); SUM(BIGNUMERIC) в [1:8]
Я нашел ARRAY_AGG в документе, но это не то, что я хочу: он просто создает массив из значений.
Ответ №1:
Я думаю, вы хотите:
select array_agg(sum_val order by id) as res
from (
select idx, sum(val) as sum_val
from mytable t
cross join unnest(t.array_value) as val with offset as idx
group by idx
) t
Ответ №2:
Я думаю, вы хотите:
select array_agg(sum_val)
from (select (select sum(val)
from unnest(t.array_value) val
) as sum_val
from t
) x
Ответ №3:
Я думаю, технически вы просто ссылаетесь на отдельные значения в массивах, используя offset()
or safe_offset()
в случае, если могут отсутствовать значения
-- example data
with temp as (
select * from unnest([
struct(1 as id, [1, 2, 3] as array_value),
(2, [4,5,6]),
(3, [7,8])
])
)
-- actual query
select
[
SUM( array_value[safe_offset(0)] ),
SUM( array_value[safe_offset(1)] ),
SUM( array_value[safe_offset(2)] )
] as result_array
from temp
Я помещаю их в результирующий массив, но вам не обязательно это делать. У меня в последнем массиве отсутствовало одно значение, чтобы показать, что запрос не прерывается. Если вы хотите, чтобы он сломался, вы должны использовать offset()
без ‘safe_’
Комментарии:
1. Как я могу обобщить это на большой массив, скажем, с 1000 значениями? Я не хочу вручную записывать 1000 индексов
2. Я использовал электронные таблицы для написания таких запросов-частей полуавтоматически с использованием формул 😉 Поскольку вы в основном используете эти записи массива в качестве столбцов, а SQL не предоставляет функции массового или агрегирования для разных столбцов, только для строк, я не думаю, что это возможно масштабировать с помощью SQL. Вы также можете написать свой собственный конструктор запросов на python / etc. …
Ответ №4:
Ниже приведен стандартный SQL для BigQuery
select array_agg(val order by offset)
from (
select offset, sum(val) as val
from `project.dataset.table` t,
unnest(array_value) as val with offset
group by offset
)