Presto: é MAX_BY () determinístico
É a função MAX_BY()determinística. Se eu usar MAX_()para duas colunas diferentes, ambas dependendo de uma terceira, obterei o mesmo resultado de linha?
A documentação presto não menciona isso. Esta documentação sobre o mysql menciona que não, então não tenho certeza de onde encontrar essa informação.
Testei rapidamente com o seguinte:
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
Ele retornou a primeira linha, então não parece arbitrário, mas também não prova coisas.
Alguém aí pode ajudar?
Há uma questão relacionada a retornar várias colunas de uma única, MAX_BY()então estou pensando que preciso usar essa solução para garantir que o atributo da mesma linha seja selecionado: max_by com várias colunas de retorno
Respostas
Não, em caso de empate, o resultado de max_bye min_byé arbitrário. Pode parecer determinístico, mas não é um comportamento definido e pode mudar em algum ponto.
Se quiser que todos os valores sejam consistentes, você deve usar o truque ao qual se referiu, em que você empacota todas as colunas de interesse em um único valor do tipo ROW:
SELECT max_by((x1, x2, x3), y) r
FROM (...) t(y, x1, x2, x3)
Provavelmente é mais seguro e mais eficiente usar funções de janela:
select *
from (
select t.*, row_number() over(order by something desc) rn
from my_table t
) t
where rn = 1
Para este caso simples, uma cláusula de limitação de linha é realmente boa o suficiente:
select *
from my_table
order by something desc
limit 1
Ambas as consultas garantem que todos os valores retornados pertencem à mesma linha.
Nenhum, entretanto, é determinístico, no sentido de que execuções consecutivas da mesma consulta podem retornar uma linha diferente. Se você deseja um resultado estável, precisa de uma coluna (ou conjunto de colunas) que possa ser usada para identificar de forma única cada linha: adicionar idà order bycláusula seria ótimo aqui.