Presto: è MAX_BY () deterministico

Nov 07 2020

È la funzione MAX_BY()deterministica. Se utilizzo MAX_()per due colonne diverse entrambe a seconda di una terza, otterrò lo stesso risultato di riga?

La documentazione di presto non lo menziona. Questa documentazione su mysql dice che non lo è, quindi non sono sicuro di dove trovare queste informazioni.

Ho provato rapidamente con quanto segue:

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

Ha restituito la prima riga, quindi non sembra arbitrario ma non prova le cose.

Qualcuno là fuori in grado di aiutare?

C'è una domanda correlata per restituire più colonne da una singola, MAX_BY()quindi penso che sia necessario utilizzare quella soluzione per garantire che l'attributo della stessa riga sia selezionato: max_by con più colonne di ritorno

Risposte

3 MartinTraverso Nov 07 2020 at 02:23

No, in caso di parità, il risultato di max_byed min_byè arbitrario. Può sembrare deterministico, ma non è un comportamento definito e potrebbe cambiare a un certo punto.

Se vuoi che tutti i valori siano coerenti, devi usare il trucco a cui hai fatto riferimento, in cui impacchetta tutte le colonne di interesse in un unico valore di tipo ROW:

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

È probabilmente più sicuro e anche più efficiente usare le funzioni della finestra:

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

Per questo semplice caso, una clausola di limitazione delle righe è effettivamente sufficiente:

select *
from my_table 
order by something desc
limit 1

Entrambe le query garantiscono che i valori restituiti appartengano tutti alla stessa riga.

Nessuno, tuttavia, è deterministico, nel senso che esecuzioni consecutive della stessa query potrebbero restituire una riga diversa. Se vuoi un risultato stabile, allora hai bisogno di una colonna (o un insieme di colonne) che possa essere utilizzata per identificare in modo univoco ogni riga: aggiungere idalla order byclausola andrebbe bene qui.