Это не совсем ответ, но он может дать некоторые рекомендации.
Проблема заключается в отсутствии partition by
в оконной функции. Замена его эквивалентными конструкциями с использованием, скажем, row_number()
и count(*)
не поможет.
Когда я столкнулся с этим, я смог обойти его одним из двух способов.
- Если имеется много дубликатов, агрегируйте и используйте совокупные суммы для определения плиток.
- В противном случае разбейте значения на группы.
В качестве примера второй. Предполагая, что оценки варьируются от 0 до 1000, с довольно равномерным распределением. Тогда:
select t.*,
1 + floor((t.seqnum_within + tt.running_cnt - tt.cnt - 1) * 100 / cnt)
from (select t.*,
row_number() over (partition by trunc(score) order by score) as seqnum_within
from t
) t join
(select trunc(score) as score_trunc, count(*) as cnt,
sum(count(*)) over (order by min(score)) as running_cnt,
sum(count(*)) over () as total_cnt
from t
group by trunc(score)
) tt
on trunc(t.score) = score_trunc;
GROUP BY
и JOIN
должны лучше использовать параллельное оборудование.