Presto: является MAX_BY () детерминированным

Nov 07 2020

Является ли функция MAX_BY()детерминированной. Если я использую MAX_()для двух разных столбцов оба в зависимости от третьего, получу ли я тот же результат строки?

В документации presto об этом не упоминается. В этой документации по mysql упоминается, что это не так, поэтому я не уверен, где найти эту информацию.

Я быстро протестировал следующее:

WITH my_table(id, arr, something) AS (
    VALUES
        (1, ARRAY['one'], 0.0),
        (2, ARRAY['two'], 0.0),
        (3, ARRAY['three'], 0.0),
        (4, ARRAY['four'], 0.0),
        (5, ARRAY['five'], 0.0),
        (6, ARRAY[''], 0.0)
)
SELECT
    MAX_BY(id,something),
    MAX_BY(arr,something)
FROM my_table

Он вернул первую строку, так что это не кажется произвольным, но и не доказывает.

Кто-нибудь может помочь?

Существует связанный вопрос о возврате нескольких столбцов из одного, MAX_BY()поэтому я думаю, что мне нужно использовать это решение, чтобы гарантировать, что атрибут той же строки выбран: max_by с несколькими столбцами возврата

Ответы

3 MartinTraverso Nov 07 2020 at 02:23

Нет, в случае ничьей результат max_byи min_byявляется произвольным. Это может показаться детерминированным, но это не определенное поведение и может измениться в какой-то момент.

Если вы хотите, чтобы все значения были согласованы, вы должны использовать упомянутый трюк, при котором вы упаковываете все интересующие столбцы в одно значение типа ROW:

SELECT max_by((x1, x2, x3), y) r
FROM (...) t(y, x1, x2, x3)
1 GMB Nov 07 2020 at 01:46

Вероятно, безопаснее и эффективнее использовать оконные функции:

select *
from (
    select t.*, row_number() over(order by something desc) rn
    from my_table t
) t
where rn = 1

В этом простом случае предложение, ограничивающее количество строк, действительно подходит:

select *
from my_table 
order by something desc
limit 1

Оба запроса гарантируют, что все возвращаемые значения принадлежат одной строке.

Однако ни один из них не является детерминированным в том смысле, что последовательные выполнения одного и того же запроса могут возвращать другую строку. Если вам нужен стабильный результат, вам понадобится столбец (или набор столбцов), который можно использовать для однозначной идентификации каждой строки: добавление idк order byпредложению здесь вполне подойдет.