点击上方蓝字关注我们

问题描述



数据准备


1)表结构

2)建表语句
DROP TABLE IF EXISTS user_login_detail;CREATE TABLE user_login_detail(`user_id` string comment '用户id',`ip_address` string comment 'ip地址',`login_ts` string comment '登录时间',`logout_ts` string comment '登出时间') COMMENT '用户登录明细表'ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
3)数据装载
INSERT overwrite table user_login_detailVALUES ('101', '180.149.130.161', '2021-09-21 08:00:00', '2021-09-27 08:30:00'),('101', '180.149.130.161', '2021-09-27 08:00:00', '2021-09-27 08:30:00'),('101', '180.149.130.161', '2021-09-28 09:00:00', '2021-09-28 09:10:00'),('101', '180.149.130.161', '2021-09-29 13:30:00', '2021-09-29 13:50:00'),('101', '180.149.130.161', '2021-09-30 20:00:00', '2021-09-30 20:10:00'),('102', '120.245.11.2', '2021-09-22 09:00:00', '2021-09-27 09:30:00'),('102', '120.245.11.2', '2021-10-01 08:00:00', '2021-10-01 08:30:00'),('102', '180.149.130.174', '2021-10-01 07:50:00', '2021-10-01 08:20:00'),('102', '120.245.11.2', '2021-10-02 08:00:00', '2021-10-02 08:30:00'),('103', '27.184.97.3', '2021-09-23 10:00:00', '2021-09-27 10:30:00'),('103', '27.184.97.3', '2021-10-03 07:50:00', '2021-10-03 09:20:00'),('104', '27.184.97.34', '2021-09-24 11:00:00', '2021-09-27 11:30:00'),('104', '27.184.97.34', '2021-10-03 07:50:00', '2021-10-03 08:20:00'),('104', '27.184.97.34', '2021-10-03 08:50:00', '2021-10-03 10:20:00'),('104', '120.245.11.89', '2021-10-03 08:40:00', '2021-10-03 10:30:00'),('105', '119.180.192.212', '2021-10-04 09:10:00', '2021-10-04 09:30:00'),('106', '119.180.192.66', '2021-10-04 08:40:00', '2021-10-04 10:30:00'),('106', '119.180.192.66', '2021-10-05 21:50:00', '2021-10-05 22:40:00'),('107', '219.134.104.7', '2021-09-25 12:00:00', '2021-09-27 12:30:00'),('107', '219.134.104.7', '2021-10-05 22:00:00', '2021-10-05 23:00:00'),('107', '219.134.104.7', '2021-10-06 09:10:00', '2021-10-06 10:20:00'),('107', '27.184.97.46', '2021-10-06 09:00:00', '2021-10-06 10:00:00'),('108', '101.227.131.22', '2021-10-06 09:00:00', '2021-10-06 10:00:00'),('108', '101.227.131.22', '2021-10-06 22:00:00', '2021-10-06 23:00:00'),('109', '101.227.131.29', '2021-09-26 13:00:00', '2021-09-27 13:30:00'),('109', '101.227.131.29', '2021-10-06 08:50:00', '2021-10-06 10:20:00'),('109', '101.227.131.29', '2021-10-08 09:00:00', '2021-10-08 09:10:00'),('1010', '119.180.192.10', '2021-09-27 14:00:00', '2021-09-27 14:30:00'),('1010', '119.180.192.10', '2021-10-09 08:50:00', '2021-10-09 10:20:00');
问题分析


代码实现
-- 求连续并标志是连续的第几天selectt1.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_cnfrom(selectuser_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')) rkfromuser_login_detailgroup byuser_id,date_format(login_ts,'yyyy-MM-dd'))t1--求出金币数量,以及签到奖励的金币数量selectt2.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_cnfrom(selectt1.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_cnfrom(selectuser_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')) rkfromuser_login_detailgroup byuser_id,date_format(login_ts,'yyyy-MM-dd'))t1)t2group byt2.user_id,t2.login_date_rk-- 求出每个用户的金币总数selectt3.user_id,sum(t3.coin_cn) sum_coin_cnfrom(selectt2.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_cnfrom(selectt1.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_cnfrom(selectuser_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')) rkfromuser_login_detailgroup byuser_id,date_format(login_ts,'yyyy-MM-dd'))t1)t2group byt2.user_id,t2.login_date_rk)t3group byt3.user_idorder bysum_coin_cn desc
代码功能分析
功能: 计算每个用户的金币总数。 实现方式: 将第二段 SQL 的查询结果作为子查询 t3。 主查询中: 使用 sum(t3.coin_cn) 计算每个用户的金币总数 sum_coin_cn。 按照 user_id 分组并按照 sum_coin_cn 降序排序。 整个 SQL 代码通过窗口函数和日期计算,将用户登录数据进行了复杂的分析和处理。 首先使用 RANK() 函数对用户的登录日期进行排序和排名,为后续计算连续登录提供基础。 通过 DATE_SUB() 函数结合排名,找出连续登录的序列,并计算连续登录天数。 然后根据连续登录天数的规则,使用 IF() 函数和 SUM() 函数添加相应的金币奖励。 最后对用户的金币数进行求和并排序,以展示用户的金币总数排名。
小结



往期回顾
SQL进阶技巧:如何计算商品需求与到货队列表进出计划?

END

公众号:会飞一十六
扫码关注 了解更多内容
点个在看,你最好看

点击“阅读原文”获取更多精彩内容~~
文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。






