mysql 连续打卡天数_Sql如何统计连续打卡天数?

本文介绍了如何使用MySQL解决统计连续打卡天数的问题,通过窗口函数row_number()获取打卡排名,并通过日期与排名的差值找出连续打卡的天数。文章提供了获取最近和历史最长连续打卡天数的方法,并强调了口径问题的重要性。
摘要由CSDN通过智能技术生成

今天来解一道题面试中可能经常会被一些面试官拿来“刁难”的题,就是《如何统计连续打卡天数》,当然了这里面的打卡可以换成任意其他行为,比如连续登陆天数,连续学习天数,连续购买天数,这里的天数也是可以换成小时或者别的时间单位的。这个问题的逻辑还是有点复杂,如果要是之前没遇到过这种问题,当场被问到的时候,肯定会一脸懵。

直接来看实战,现在有一张表t,这张表存储了每个员工每天的打卡情况,现在需要统计截止目前每个员工的连续打卡天数,表t如下表所示:

d0d0340b30fd60cdc91eb7a1e39bed07.png

上表中uid是用户id,tdate是日期,is_flag是记录用户当天是否打卡,1为打卡,0为未打卡。

我们希望得到的结果为:

471a7372eda455173f5bbb56438ea092.png

这个逻辑还是挺难想的,第一个想法就是通过前后数据偏移来实现,就是将is_flag向前移动一行或者向后移动一行,然后和原来的is_flag标签做差,如果结果为0,说明前后两天的值是相同的,要么都是0,要么都是1。但是还是不能够得出我们想要的结果。

再换一种思路:如果

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 MySQL 的日期函数和子查询实现连续日期统计,具体步骤如下: 1. 构造一个包含所有需要统计的日期的临时表,可以使用 UNION ALL 来实现,例如统计从 2022-01-01 到 2022-01-31 的日期: ``` SELECT DATE('2022-01-01') AS date UNION ALL SELECT DATE('2022-01-02') UNION ALL SELECT DATE('2022-01-03') ... UNION ALL SELECT DATE('2022-01-31'); ``` 2. 使用子查询查询连续出现的天数,首先需要找到每个连续日期段的起始日期和结束日期,可以通过自连接的方式实现。假设有一个名为 `date_table` 的表存储了所有需要统计的日期,可以使用以下 SQL 语句查询连续日期段: ``` SELECT a.date AS start_date, MIN(c.date) AS end_date FROM date_table a LEFT JOIN date_table b ON b.date = DATE_SUB(a.date, INTERVAL 1 DAY) LEFT JOIN date_table c ON c.date = DATE_ADD(a.date, INTERVAL 1 DAY) WHERE b.date IS NULL OR c.date IS NULL GROUP BY a.date; ``` 上述 SQL 语句会找到所有连续出现的日期段的起始日期和结束日期,例如: ``` +------------+------------+ | start_date | end_date | +------------+------------+ | 2022-01-01 | 2022-01-01 | | 2022-01-02 | 2022-01-03 | | 2022-01-04 | 2022-01-04 | | 2022-01-07 | 2022-01-08 | | 2022-01-09 | 2022-01-09 | | 2022-01-10 | 2022-01-10 | +------------+------------+ ``` 3. 使用上一步查询到的连续日期段,结合日期函数和 GROUP BY 子句,统计每个连续日期段内的天数: ``` SELECT start_date, end_date, COUNT(*) AS count FROM ( SELECT a.date AS start_date, MIN(c.date) AS end_date FROM date_table a LEFT JOIN date_table b ON b.date = DATE_SUB(a.date, INTERVAL 1 DAY) LEFT JOIN date_table c ON c.date = DATE_ADD(a.date, INTERVAL 1 DAY) WHERE b.date IS NULL OR c.date IS NULL GROUP BY a.date ) AS t JOIN date_table d ON d.date BETWEEN t.start_date AND t.end_date GROUP BY start_date, end_date; ``` 上述 SQL 语句会输出每个连续日期段的起始日期、结束日期和连续出现的天数,例如: ``` +------------+------------+-------+ | start_date | end_date | count | +------------+------------+-------+ | 2022-01-01 | 2022-01-01 | 1 | | 2022-01-02 | 2022-01-03 | 2 | | 2022-01-04 | 2022-01-04 | 1 | | 2022-01-07 | 2022-01-08 | 2 | | 2022-01-09 | 2022-01-09 | 1 | | 2022-01-10 | 2022-01-10 | 1 | +------------+------------+-------+ ``` 注意,上述 SQL 语句中的 `date_table` 表需要根据实际情况替换为实际的表名或子查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值