Hive综合案例练习(中级)第三十八题:连续签到领金币数

连续签到领金币数

题目需求

用户每天签到可以领1金币,并可以累计签到天数,连续签到的第3、7天分别可以额外领2和6金币。

每连续签到7天重新累积签到天数。

从用户登录明细表中求出每个用户金币总数,并按照金币总数倒序排序

结果如下:

User_id(用户id) Sum_coin_cn(金币总数)
101 7
109 3
107 3
102 3
106 2
104 2
103 2
1010 2
108 1
105 1

思路:求出截至到目前用户连续登录的天数,按照coins=max(登录天数)+sum(if(登录天数%3=0, 2, 0))+sum(if(登录天数%7=0, 6, 0)求取金币总数。

第一步:因用户存在一天多次登录的情况,按照用户和登录日期去重并开窗按照用户分组按照登录日期排序进行排名;

第二步:如果登录日期减去排名(记为连续登录标记)相等,则用户处在连续登录。按照用户、连续登录标记计数求出截至到目前用户连续登录的天数;

第三步:按照用户、连续登录标记和公式coins=max(登录天数)+sum(if(登录天数%3=0, 2, 0))+sum(if(登录天数%7=0, 6, 0)求取用户每个连续登录的金币总数。

第四步:求出每个用户的金币总数并排序

代码实现

-- 求连续并标志是连续的第几天
select
  t1.user_id,
  t1.login_date,
  date_sub(t1.login_date,t1.rk) login_date_rk,
  count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
from
  (
   select
     user_id,
     date_format(login_ts,'yyyy-MM-dd') login_date,
     rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
   from
     user_login_detail
   group by
     user_id,date_format(login_ts,'yyyy-MM-dd')
)t1

--求出金币数量,以及签到奖励的金币数量
select
  t2.user_id,
  max(t2.counti_cn)+sum(if(t2.counti_cn%3=0,2,0))+sum(if(t2.counti_cn%7=0,6,0)) coin_cn
from
  (
select
  t1.user_id,
     t1.login_date,
     date_sub(t1.login_date,t1.rk) login_date_rk,
     count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
   from
     (
      select
        user_id,
        date_format(login_ts,'yyyy-MM-dd') login_date,
        rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
      from
        user_login_detail
      group by
        user_id,date_format(login_ts,'yyyy-MM-dd')
   )t1
)t2
group by
  t2.user_id,t2.login_date_rk

-- 求出每个用户的金币总数
select
  t3.user_id,
  sum(t3.coin_cn) sum_coin_cn
from 
  (
    select
      t2.user_id,
      max(t2.counti_cn)+sum(if(t2.counti_cn%3=0,2,0))+sum(if(t2.counti_cn%7=0,6,0)) coin_cn
    from
      (
    select
      t1.user_id,
         t1.login_date,
         date_sub(t1.login_date,t1.rk) login_date_rk,
         count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
       from
         (
          select
            user_id,
            date_format(login_ts,'yyyy-MM-dd') login_date,
            rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
          from
            user_login_detail
          group by
            user_id,date_format(login_ts,'yyyy-MM-dd')
       )t1
    )t2
    group by
      t2.user_id,t2.login_date_rk
    )t3
group by
  t3.user_id
order by
  sum_coin_cn desc

你可能感兴趣的:(Hive综合案例练习,hive,hadoop,数据仓库)