Есть ли обходной путь для агрегации argmin / argmax в Snowflake? - PullRequest
1 голос
/ 19 февраля 2020

Я ищу способ вычисления агрегирования argmin или argmax нескольких строк в Snowflake, аналогично Hive или Presto.

В Hive можно использовать обходной путь с (именованными) структурами, потому что функция агрегирования получает применяется к первому элементу структуры. Вот пример:

SELECT max(named_struct('y', y, 'x', x)).x FROM t

Теперь я спрашиваю себя, есть ли подобный способ сделать это в Snowflake.

В Snowflake у нас есть тип данных OBJECT со схожими свойствами. Могу ли я использовать следующий код для вычисления argmin или argmax, как в примере с Hive? Выполнены ли агрегации мин / макс для объектов также для первого элемента объекта?

SELECT max(object_construct('y', y, 'x', x)).x FROM t

Запуск приведенного выше кода возвращает ошибку: SQL compilation error: Function MAX does not support OBJECT argument type.. На самом деле он не поддерживает сложный тип.

1 Ответ

0 голосов
/ 19 февраля 2020

Если я правильно понял логи c функции argmin (), то вы могли бы реализовать ее как javascript UDF, например, так:

create or replace function argmin("a" object, "b" object)
  returns object
  language javascript
as
$$

    for (let [k,v] of Object.entries(a))
        if (v==b[k])
            continue
        else 
            return v < b[k] ? a : b

    return b

$$;

И применить так:

with t as (
  select 
     object_construct('x',1, 'y',2) a, 
     object_construct('x',2, 'y',1) b
)
select argmin(t.a,t.b):y from t;

На самом деле эта функция встроена:

select 
    object_construct('x',1, 'y',2) a, 
    object_construct('x',2, 'y',1) b, 
    iff(a<b, a, b) : y
;

Еще более кратко:

select 
   object_construct('x',1, 'y',2) a, 
   object_construct('x',2, 'y',1) b,
   least(a,b):y,
   greatest(a,b):y;
...