百度一面SQL之连续签到领金币

推荐阅读文章列表

大数据开发面经汇总【持续更新...】

我的大数据学习之路

大数据开发面试笔记V6.0

SQL题目

来自牛客SQL题库

  • 已知一张用户行为日志表tb_user_log,字段包括uid-用户ID、artical_id-文章ID、in_time-进入时间、out_time-离开时间、sign_in-是否签到
  • 注意1:只有artical_id为0时sign_in值才有效;
  • 注意2:从2021年7月7日0点开始,用户每天签到可以领1金币,并可以开始累积签到天数,连续签到的第3、7天分别可额外领2、6金币,每连续签到7天后重新累积签到天数
  • 问题:计算每个用户2021年7月至10月每月获得的金币数

答案解析

模拟数据

CREATE TABLE tb_user_log (
    uid INT COMMENT '用户ID',
    artical_id INT COMMENT '视频ID',
    in_time varchar(20) COMMENT '进入时间',
    out_time varchar(20) COMMENT '离开时间',
    sign_in int COMMENT '是否签到'
) ;
 
INSERT INTO tb_user_log(uid, artical_id, in_time, out_time, sign_in) VALUES
  (101, 0, '2021-07-07 10:00:00', '2021-07-07 10:00:09', 1),
  (101, 0, '2021-07-08 10:00:00', '2021-07-08 10:00:09', 1),
  (101, 0, '2021-07-09 10:00:00', '2021-07-09 10:00:42', 1),
  (101, 0, '2021-07-10 10:00:00', '2021-07-10 10:00:09', 1),
  (101, 0, '2021-07-11 23:59:55', '2021-07-11 23:59:59', 1),
  (101, 0, '2021-07-12 10:00:28', '2021-07-12 10:00:50', 1),
  (101, 0, '2021-07-13 10:00:28', '2021-07-13 10:00:50', 1),
  (101, 0, '2021-07-14 11:00:28', '2021-07-14 11:00:50', 1),
  (101, 0, '2021-07-15 11:59:28', '2021-07-16 00:01:20', 1),
  (102, 0, '2021-10-01 10:00:28', '2021-10-01 10:00:50', 1),
  (102, 0, '2021-10-02 10:00:01', '2021-10-02 10:01:50', 1),
  (102, 0, '2021-10-03 11:00:55', '2021-10-03 11:00:59', 1),
  (102, 0, '2021-10-04 11:00:45', '2021-10-04 11:00:55', 0),
  (102, 0, '2021-10-05 11:00:53', '2021-10-05 11:00:59', 1),
  (102, 0, '2021-10-06 11:00:45', '2021-10-06 11:00:55', 1);

alt

思路分析

  • 根据题目"连续"二字可知,此SQL题在考察连续问题,可以套用本人总结的连续问题模板(见之前的文章)
  • 需求拆解如下:
    • 题目要求每个月用户领金币的数量,假设知道用户每日可以领到的金币数量,问题就迎刃而解了
    • 要想求每日用户领到的金币数量,只需要关注三个特殊节点,连续3天签到+2个金币,连续7天签到+6个金币,7天后领取金币数量为1
    • 如何判断是否连续签到3天/7天?
    • 固定套路:首先对用户按照签到时间进行排序得到rn1,然后按照 用户和签到时间减去rn1进行分组,签到时间进行排序得到rn2
    • 得到rn2之后,就可以很容易得到每日用户签到领取的金币数量

具体代码

SELECT
	uid,DATE_FORMAT(dt,'%Y%m') `month`, sum(day_coin) coin  
FROM
	( 
		SELECT
	*,
	DATE_SUB(dt,INTERVAL rn day) dt_tmp, 
	case row_number() over(PARTITION BY DATE_SUB(dt,INTERVAL rn day),uid ORDER BY dt )%7 
		WHEN 3 THEN 3
		WHEN 0 THEN 7
		ELSE 1
	END as day_coin 
	FROM (
			SELECT
		uid,
		date(in_time) dt,
		row_number() over(partition BY uid ORDER BY date(in_time)) rn 
	FROM
		tb_user_log
	WHERE
		DATE(in_time) BETWEEN '2021-07-07' AND '2021-10-31' AND artical_id = 0 AND sign_in = 1
	) t
) t
GROUP BY
	uid, DATE_FORMAT(dt,'%Y%m')
;

alt

#数据人的面试交流地##校招过来人的经验分享#
全部评论

相关推荐

05-26 22:25
门头沟学院 Java
Java小肖:不会是想叫你过去把你打一顿吧,哈哈哈
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 12:31
以前小时候我最痛恨出轨、偷情的人,无论男女,为什么会出轨?现在我成了自己最讨厌的人,没想到分享的东西在牛客会被这么多人看,大家的评价都很中肯,我也认同,想过一一回复,但我还是收声了,我想我应该说说这件事,这件事一直压在我心里,是个很大的心结,上面说了人为什么出轨,我大概能明白了。我们大一下半年开始恋爱,开始恋爱,我给出了我铭记3年的承诺,我对她好一辈子,我永远不会背叛,我责任心太重,我觉得跟了我,我就要照顾她一辈子,我们在一起3年我都没有碰过她,她说往东我就往东,她说什么我做什么,她要我干什么,我就干什么!在学校很美好,中途也出过一些小插曲,比如男闺蜜、男闺蜜2号等等等。但我都强迫她改掉了,我...
牛客刘北:两个缺爱的人是没有办法好好在一起的,但世界上哪有什么是非对错?你后悔你们在一起了,但是刚刚在一起的美好也是真的呀,因为其他人的出现,你开始想要了最开始的自己,你的确对不起自己,21岁的你望高物远,你完全可以不谈恋爱,去过你想要的生活,你向往自由,在一起之后,你要想的不是一个人,而是两个人,你不是变心了,就像你说的,你受够了,你不想包容了,冷静几天是你最优的选择,爱人先爱己。
社会教会你的第一课
点赞 评论 收藏
分享
评论
6
13
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务