一、题目

在活动大促中,有玩游戏瓜分奖金环节。现有奖金池为 10000元,代表奖金池中的初始额度。用户的分数信息如下表。表中的数据代表每一个用户和其对应的得分,user_id 和 score 都不会有重复值。瓜分奖金的规则如下:按照 score 从高到低依次瓜分,每个人都能分走当前奖金池里面剩余奖金的一半,当奖金池里面剩余的奖金少于 250 时(不含),则停止瓜分奖金。 现在需要查询出所有分到奖金的 user_id 和其对应的奖金。

二、思路

有两个已知的条件:1)用户和成绩没有重复,不会出现分数相同的情况 2)奖金池的奖金数不能低于250. 基于此如果每个人分奖金池一般的奖金那么第一个人分1/2,第二个人分1/4,第三个人分1/8,依此类推。所以每个人分的奖金其实是10000*(1/2)的n次方。知识点:pow()

-- 10000 * 1/2 = 5000

-- 10000 * 1/4 = 2500

-- 10000 * 1/8 = 1250

三、解答

select 
  user_id,
  score,
  bonus
from (
  select 
    user_id,
    score,
    10000 * pow(1/2, rank() over(order by score desc)) bonus,
    rank() over(order by score desc) rk
  from jjc_user_score 
) t11
where bonus > 250

结果:

数据

# 建表
--建表语句
create table if not exists jjc_user_score (
    user_id string,
    score   bigint
)
stored as parquet
;
 
--插入数据
insert into jjc_user_score(user_id, score) values
('100',60),
('101',45),
('103',35),
('104',30),
('105',25),
('106',15),
('107',10);

注:题目获取自网络