Spark SQL не может УМЕНЬШИТЬ массив bigint

#sql #apache-spark #apache-spark-sql

Вопрос:

Я работаю с databricks 8 с кластером Spark 3.1.1. У меня есть столбец температуры, который содержит и массив bigint, но я получаю ошибку, когда хочу обработать среднее значение массива с:

 SELECT
temps,
REDUCE(temps, 0, (t, acc) -> t   acc, acc ->(acc div size(temps))) as avg_daily_temp_c
FROM data
 

В этом и заключается ошибка:

Ошибка в инструкции SQL: Исключение AnalysisException: не удается разрешить » агрегат(spark_catalog.по умолчанию.device_part. temps , 0, лямбдафункция((ПРИВЕДЕНИЕ(namedlambdavariable() КАК BIGINT) namedlambdavariable()), namedlambdavariable(), namedlambdavariable()), лямбдафункция((ПРИВЕДЕНИЕ(namedlambdavariable() КАК BIGINT) div ПРИВЕДЕНИЕ(размер(spark_catalog.по умолчанию.часть устройства. temps ) КАК BIGINT)), namedlambdavariable ()))’ из-за несоответствия типов данных: аргумент 3 требует типа int, однако » функция lambd ((ПРИВЕДЕНИЕ(namedlambdavariable() КАК BIGINT) namedlambdavariable()), namedlambdavariable(), namedlambdavariable (), namedlambdavariable ())» имеет тип bigint.; строка 2 поз 2; Проект [темп#1855, агрегат(темп#1855, 0, лямбда-функция((приведение(лямбда-т#1857 как бигинт) лямбда-акк#1858L), лямбда-т#1857, лямбда-акк#1858L, ложь), лямбда-функция((приведение(лямбда-акк#1859 как бигинт) div приведение(размер(темп#1855, истина) как бигинт)), лямбда-акк#1859, ложь)) КАК avg_daily_temp_c#1842L, время#1856] — Подзапрос spark_catalog.по умолчанию.device_part — Relation[battery_level#1850,co2_level#1851,p_device_id#1852L,device_type#1853,signal#1854,temps#1855,time#1856] паркет

С другим столбцом array-int вообще нет проблем с тем же кодом. Любой совет будет очень признателен.

Ответ №1:

Вы можете явно приводить типы, чтобы предотвратить ошибки такого рода:

 SELECT
temps,
REDUCE(temps, cast(0 as bigint), (t, acc) -> cast(t as bigint)   cast(acc as bigint), acc -> (acc div size(temps))) as avg_daily_temp_c
FROM data
 

Ответ №2:

Поскольку temps это массив bigint , вам нужно только привести начальное значение к bigint :

 SELECT
  temps,
  REDUCE(temps, cast(0 as bigint), (t, acc) -> t   acc, acc ->(acc div size(temps))) as avg_daily_temp_c
FROM data
 

В качестве альтернативы вместо reduce функции вы можете использовать aggregate функцию.