SQL-计算连续签到天数

news2024/12/23 14:04:38

1、应用场景

现在有一份用户签到行为数据,记录了用户ID,签到日期。

在业务场景中,通常会要求用户连续签到,如果断签则要重新开始计数。

所以需要基于上述数据,计算筛选出连续签到天数大于n天的用户。

日期用户ID
2022-01-01A
2022-01-02A
2022-01-02B
2022-01-03B
2022-01-05B

2、实现思路

step1:根据用户的签到日期,利用窗口函数计算这是第几天签到。

如果同一天不能重复签到的话,那么三种排序函数都可用。但是如果同一天可以重复签到,则需要使用重复连续的dense_rank()over()函数。

三种排序函数在遇到重复值时的排序规则对比如下:

  • dense_rank(),并列连续,1-2-2-3
  • rank(),并列不连续,1-2-2-4
  • row_number() ,不并列,1-2-3-4

窗口函数知识点回顾:

SQL-窗口函数知识点及案例学习_格勒王的博客-CSDN博客窗口函数的初步介绍,学习如何使用窗口函数计算排序、推移和累加求和等操作https://blog.csdn.net/weixin_47198715/article/details/130829177?spm=1001.2014.3001.5502

select 
  user_id,
  date,
  from_unixtime(unix_timestamp(date,'yyyymmdd'),'yyyy-mm-dd') as date_long,
  row_number()over(partition BY user_id order by date) as rn
  from table_name
  

得到如下结果:可以发现这里的日期排序完全没有考虑日期是否连续的问题

日期用户ID日期排序
2022-01-01A1
2022-01-02A2
2022-01-02B1
2022-01-03B2
2022-01-05B3

step2: 计算当前签到日期-日期排序序号

当前签到日期-日期排序序号之后得到的日期值的含义是:如果用户是连续签到的,那么当前日期对应的首次签到日期应该是几号。

这里注意:最好把日期提前转换为yyyy-mm-dd格式,便于时间加减运算

select
  user_id,
  date,
  rn,
  date_sub(date_long,rn) as date_first
from
  (select 
  user_id,
  date,
  from_unixtime(unix_timestamp(date,'yyyymmdd'),'yyyy-mm-dd') as date_long,
  row_number()over(partition BY user_id order by date) as rn
  from table_name)a
  
日期用户ID日期排序date_first
2022-01-01A12021-12-31
2022-01-02A22021-12-31
2022-01-02B12022-01-01
2022-01-03B22022-01-01
2022-01-05B32022-01-02

根据结果可以理解,如果用户是连续签到,那么连续签到的几天对应的首次日期是一致的

B用户在20220105号进行了第3次签到,而如果是连续的,20220105日的签到排序应该是第4次,date_first是2022-01-01。但实际上,用户B在20220105日只进行了第3次签到,说明出现了断签情况。

step3:按照date_first(即假定连续签到下的首次签到时间)和用户ID分组,统计该分组下的日期数

select
 user_id,
 date_first,
 count(distinct date) as `连续签到天数`
from 
(select
  user_id,
  date,
  rn,
  date_sub(date_long,rn) as date_first
from
  (select 
  user_id,
  date,
  from_unixtime(unix_timestamp(date,'yyyymmdd'),'yyyy-mm-dd') as date_long,
  row_number()over(partition BY user_id order by date) as rn
  from table_name)a
 )a
group by user_id,date_first
date_first用户ID连续天数
2022-01-01A2
2022-01-01B2
2022-01-02B1

step4:取每个用户连续天数最大值

完整代码

select user_id,max(`连续签到天数`)
from 
(select
 user_id,
 date_first,
 count(distinct date) as `连续签到天数`
from 
(select
  user_id,
  date,
  rn,
  date_sub(date_long,rn) as date_first
from
  (select 
  user_id,
  date,
  from_unixtime(unix_timestamp(date,'yyyymmdd'),'yyyy-mm-dd') as date_long,
  row_number()over(partition BY user_id order by date) as rn
  from table_name)a
 )a
group by user_id,date_first)a
group by user_id

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/595557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python仿真模拟:介绍与应用

Python仿真模拟:介绍与应用 Python是一种流行的编程语言,其与技术仿真的结合越来越受欢迎, 广泛用于各种仿真和模拟应用程序中。在本文中,我们将介绍Python仿真模拟的基本原理,及其在不同领域中的应用和优势。 什么是…

在酒店房间中的数据库索引

如果你经常去酒店,你会看到一块类似下面的标牌,指引你到达房间。这能够帮助你方便快速地找到房间,特别是当酒店拥有许多房间时。 以一个有9层的酒店为例。你的房间号是917。第一步是找到你的房间在哪一层,通常第一个数字表示楼层…

[数据结构习题]链表——单链表重排

[数据结构习题]链表——单链表重排 👉知识点导航💎:【数据结构】线性表——顺序存储 👉知识点导航💎:【数据结构】线性表——链式存储 👉[王道数据结构]习题导航💎: p …

DAY02_MySQL高级-约束数据库设计多表查询事务

目录 1 约束1.1 概念1.2 分类1.3 非空约束1.4 唯一约束1.5 主键约束1.6 默认约束1.7 约束练习1.7.1 修改自增序列号 1.8 外键约束1.8.1 概述1.8.2 语法1.8.3 练习 2 数据库设计2.1 数据库设计简介2.2 表关系(一对多)2.3 表关系(多对多)2.4 表关系(一对一)2.5 数据库设计案例 3 …

kubernetes之client-go informer源码分析

一、概念 informer 是 client-go 中的核心工具包,在kubernetes中,各个组件通过HTTP协议跟 API Server 进行通信。如果各组件每次都直接和API Server 进行交互,会给API Server 和ETCD造成非常大的压力。在不依赖任何中间件的情况下&#xff0…

从零开始手写VIO 第3讲 基于优化的 IMU 与视觉信息融合

技巧性u初始值,更新的原因都不知道杂来的 F(x)是复杂的非线性函数,所以没法直接求导0得到最小值。所以展开 两种方法来下降,一种是先找一个方向,在确定一个步长line search。另一种是先确定区域,再找一个点。 J是FX的雅…

docker架构速看(1)-启动

Docker架构速看(1)-启动 ​ Docker是常用的容器管理工具,这篇文章对Docker架构结合源码做简要分析,由于也只使用过很少的命令,所以只分析image和container的相关部分。 源码准备 ​ Docker源码可以在github上找到,当前已更名为…

Vector-常用CAN工具 - VN5000接口以太网包过滤

目录 一、什么是硬件过滤? 1、什么时候应该过滤硬件? 2、需要注意什么? 3、如何过滤VN5000接口上的以太网报文? (1)Vector Hardware Manager (2)Vector Hardware Config 一、…

Benewake(北醒) 快速实现 TF03-485 与电脑通信操作说明

目录 一、前言二、工具准备1. USB-RS485 转接板或北醒 TF 系列专用转接板2. TF03-4853. PC:Windows 系统4. 串口助手软件、上位机 WINCC 三、连接方式方案一:USB-RS485 连接电脑与雷达(1) USB-RS485 转接板接口说明(2) TF03-485 引脚定义(3) 连接方式 方…

Go中的并发是困难的

我明白标题可能有些令人困惑,因为一般来说,Go被认为在并发方面有很好的内置支持。然而,我并不认为在Go中编写并发软件是容易的。让我向您展示我是什么意思。 使用全局变量 第一个例子是我们在项目中遇到的问题。直到最近,sarama…

【致敬未来的攻城狮计划】打卡1:rcsa+keil环境搭建

前言 这回参加的是csdn李肯老师的攻城狮计划,简单说就是我白嫖板子,输出学习笔记。 板子是瑞萨的CPK_RA2E1,还有触摸元件,看起来很有意思hh。 环境搭建 一开始决定采取vscode搭建的方式。后期进行到最后一步——cmake build的时…

SQL-计算留存率cohort

目录 1、留存率cohort介绍及其业务价值 2、计算思路 3、实操 3.1、日对日留存cohort 3.2、周对周留存cohort 3.3、月对月留存cohort 1、留存率cohort介绍及其业务价值 留存率cohort也叫做同期群留存分析,将同一时间范围内的用户分为一组,计算这批…

Linux命令(26)之uptime

Linux命令之uptime 1.uptime介绍 linux命令uptime是用来为用户提供系统从开启到当前运行uptime命令时系统已运行的时长信息,除此之外,还提了系统启动时间,当前登录用户,系统平均负载信息。 2.uptime用法 uptime [参数] uptime…

华为OD机试真题(Java),四则运算(100%通过+复盘思路)

一、题目描述 输入一个表达式(用字符串表示),求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。 数据范围:表达…

gitlab记录

1、docker方式部署启动 参考文档: https://blog.csdn.net/weixin_53443677/article/details/125518696 https://blog.csdn.net/weixin_39034012/article/details/119211630 1.1、docker启动gitlab 前期准备 > # 拉镜像 > docker pull gitlab/gitlab-ce:late…

chatgpt赋能python:Python代码30行:提高网站SEO的最佳实践

Python 代码 30 行:提高网站 SEO 的最佳实践 搜索引擎优化(SEO)是网站成功的重要因素,它可以让网站排名更高并吸引更多的流量。Python 代码可以帮助您实现最佳的 SEO 实践,并提高网站的可见性和排名。下面是一个包含 …

Tugraph的设计和源码初步解析

1. Tugraph Tugraph是一款开源的性能优秀的图数据库,该图数据库使用多版本的BTree作为数据的存储引擎,同时设置了点边数据在这个存储引擎上的布局(主要考虑数据的局部性),从而达到高性能查询的目的。本文主要从Tugrap…

ubuntu系统登录密码重置方法

公司搬家,需要更改git服务器地址,发现服务器密码也忘记了,折腾了下,通过如下方法修改成功。 一、重启计算机并进入GRUB菜单(如果您的计算机没有显示GRUB菜单,请尝试按住Shift键或Esc键,直到出现…

手机安卓Termux搭建Hexo博客网站,并发布公网访问。

文章目录 1. 安装 Hexo2. 安装cpolar内网穿透3. 公网远程访问4. 固定公网地址 转载自cpolar极点云的文章:安卓手机使用Termux搭建Hexo个人博客网站【内网穿透公网访问】 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#…

DAY04_JDBC快速入门JDBC API详解SQL防注入数据库连接池JDBC综合练习

目录 1 JDBC1.1 JDBC概念1.2 JDBC本质 1.3 JDBC好处 2 JDBC快速入门2.1 编写代码步骤2.2 具体操作 3 JDBC API详解3.1 DriverManager3.2 Connection3.2.1 获取执行对象3.2.2 事务管理 3.3 Statement3.4 ResultSet3.4.1 ResultSet案例 3.5 PreparedStatement3.5.1 SQL注入3.5.2 …