HQL || SQL :连续签到领金币

embedded/2024/10/19 14:36:55/

  • 已知一张用户行为日志表tb_user_log,字段包括uid-用户IDartical_id-文章IDin_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-14 10:00:28', '2021-07-13 10:00:50', 1),(101, 0, '2021-07-15 11:00:28', '2021-07-14 11:00:50', 1),(101, 0, '2021-07-16 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-05 11:00:45', '2021-10-04 11:00:55', 0),(102, 0, '2021-10-06 11:00:53', '2021-10-05 11:00:59', 1),(102, 0, '2021-10-07 11:00:45', '2021-10-06 11:00:55', 1);

思路分析:

为了计算每日用户领取的金币数量,我们需要关注三个关键节点:

1. 连续签到3天,额外获得2个金币(共领取3个金币)。

2. 连续签到7天,额外获得6个金币(共领取7个金币)。

3. 在其余情况下,每天领取1个金币。

  • 如何判断是否连续签到3天/7天?

思路:

我们需要将一段连续的签到日期分成一组,再将这段日期组别进行组内排序最终判断金币数

所以该题的难度是如何进行分组:

分组策略:

1. 排序与排名: - 使用ROW_NUMBER()函数对用户的签到记录按日期排序,并为每条记录生成一个唯一的排名rn

sql">row_number() OVER (PARTITION BY uid ORDER BY DATE(in_time)) as rn

2. 日期分组: - 利用DATE_SUB(dt, INTERVAL rn DAY)对签到日期进行转换,其中dt是签到日期,rn是排序后的排名。这样处理后,连续签到的日期将转换到相同的值,从而实现分组。

然后再使用ROW_NUMBER()函数对组内连续日期进行排序并 % 7 进行判断后计算金币数

sql"> case row_number() over(partition by uid,date_sub(dt, interval rn day) order by dt)%7when 3 then 3when 7 then 7 else 1end as day_coin

date              rn          group
2021-07-07   1             2021-07-06 
2021-07-08   2             2021-07-06 
2021-07-11   3             2021-07-08 

对于签到日期2021-07-07 2021-07-08,通过DATE_SUB()函数处理后,它们都被转换到相同的日期2021-07-06 。这表明这两个签到记录是连续的,因此它们属于同一组。

签到日期2021-07-11经过相同的处理后,转换到了2021-07-08。这个结果与前两个日期的处理结果不同,,用户的签到行为中断了,因说明从2021-07-082021-07-11之间此2021-07-11属于一个新的组。

其中还有注意的是:

原数据的日期表示为这种格式:'2021-07-06 10:00:00'
我们需要使用date()函数转为这种格式:'2021-07-06 '

全部语句如下:

  
WITH t1 AS (SELECT uid,DATE(in_time) AS dt,row_number() OVER (PARTITION BY uid ORDER BY DATE(in_time)) as rnFROM tb_user_logWHEREDATE(in_time) BETWEEN '2021-07-07' AND '2021-10-31'AND artical_id = 0 AND sign_in = 1
),
t2 as (select uid,dt,-- 连续的日期会形成同一个组,然后再对组内进行一次排序。case row_number() over(partition by uid, date_sub(dt, interval rn day) order by dt)%7when 3 then 3when 7 then 7 else 1end as day_coin
from t1
)
SELECT uid,DATE_FORMAT(dt, '%Y-%m') AS month,SUM(day_coin) AS coin
FROM t2
GROUP BY uid, DATE_FORMAT(dt, '%Y-%m');


http://www.ppmy.cn/embedded/105263.html

相关文章

【react】常用插件收集

Redux状态管理 - reduxjs/toolkit 、 react-redux react-router-dom: 路由 antd-mobile: 移动端组件库 axios:请求插件 dayjs: 时间处理 classnames: class类名处理 Lodash:遍历数据等 地址→ CRACO:配置别名路径等,下载后添加craco.config.js文件…

Linux--IO模型_多路转接

目录 0.往期文章 1.五种IO模型介绍 概念 调用函数(非阻塞IO) 2.详解多路转接 之select select函数介绍 设置文件描述符 写一个基于select的TCP服务器 辅助库 基于TCP的Socket封装 服务器代码 测试服务器 小结 3.详解多路转接 之poll poll函…

Spring Boot 入门

1.1.1 什么是Spring Boot Spring Boot是一个开源的Java应用框架,由Pivotal团队提供,旨在简化Spring应用的初始搭建以及开发过程。‌ Spring Boot通过使用特定的配置方式,使得开发人员不再需要定义样板化的配置,从而在快速应用开发…

基于VsCode和Git的代码版本管理

基础回退 在项目文件夹右键打开git bash,输入命令git log 查看提交的历史 commit,git log --prettyoneline将版本信息压缩到一行 使用git log可能会显示不全,按enter逐行查看,按end跳至末尾查看完成后,按q即可退出 …

激光雷达产品介绍

与传统激光雷达线性重复式的扫描方式不同,Livox mid系列激光雷达扫描路径不会重复。且视场中激光照射到的区域面积会随时间增大,这就意味着视场覆盖率随时间推移而显著提高。 内容参考自《解构大疆旗下 Livox Mid 激光雷达非重复扫描技术》作者&#xff…

Java 输入与输出之 NIO.2【AIO】【Path、Paths、Files】【walkFileTree接口】探索之【三】

在JDK 1.7 版本中对NIO进行了完善,推出了NIO.2,也称为AIO(异步IO),在处理大量并发请求时具有优势,特别是在网络编程和高并发场景下,表现得更为出色。 对于输出流和输入流而言,操作的…

什么软件可以用平板远程控制电脑?

在当今快节奏的工作和生活中,使用平板远程控制电脑已成为一种便捷高效的办公方式。无论你是想随时随地访问办公室的电脑,还是需要在旅途中进行紧急工作任务,Splashtop都是你的不二选择。本文将介绍如何使用Splashtop通过平板远程控制电脑&…

好用的数据生产工具 mockdata

mockdata 是一个 Python 库,用于生成模拟数据。它包含各个行业各种字段,包含地址,个人信息(姓名,性别,职位等),电话,银行相关信息(信用卡,银行信息…