Если я правильно понимаю, вы можете использовать ntile()
. Например, если вы хотите значение от 1 до 4, вы можете сделать:
select t.*, ntile(4) over (order by score) as tile
from t;
Если вы хотите перечислить значения, используйте rank()
или dense_rank()
:
select t.*, rank() over (order by score) as tile
from t;
Я вижу, ваша проблема заключается в том, чтобы заставить код работать, потому что BigQuery имеет тенденцию исчерпывать ресурсы без partition by
. Один из способов - разбить счет на разные группы. Я думаю, что эта логика делает то, что вы хотите:
select *,
( (count(*) over (partition by cast(score / 1000 as int64) order by cast(score / 1000 as int64)) -
count(*) over (partition by cast(score / 1000 as int64))
) +
rank() over (partition by cast(score / 1000 as int64) order by regi_id)
) as therank,
-- rank() over (order by score) as therank
from t;
Это разбивает счет на 1000 групп (возможно, это слишком много для целого числа). А затем восстанавливает рейтинг.
Если ваша оценка имеет относительно низкое количество элементов, то join
с агрегацией работает:
select t.*, (running_cnt - cnt + 1) as therank
from t join
(select score, count(*) as cnt, sum(count(*)) over (order by score) as running_cnt
from t
group by score
) s
on t.score = s.score;
Когда у вас есть rank()
(или row_number()
), вы можете легко вычислить плитки самостоятельно (подсказка: деление).