如何仅用sql统计一个月内连续签到7天的用户呢?
数据库是mysql!
SELECT user_id
FROM (
SELECT user_id, sign_date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY sign_date) AS row_num,
DATEDIFF(sign_date,
LAG(sign_date) OVER (PARTITION BY user_id ORDER BY sign_date)
) AS diff
FROM sign_records
WHERE sign_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH)
) AS subquery
WHERE row_num >= 7 AND diff = 1
GROUP BY user_id
HAVING COUNT(*) = 7;
你可以使用SQL语句来统计一个月内连续签到7天的用户。以下是一个示例的SQL查询:
SELECT user_id
FROM (
SELECT user_id,
date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date) AS row_number,
DATEDIFF(date, '2023-07-01') - ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date) AS diff
FROM signin_table
WHERE date >= '2023-07-01' AND date <= '2023-07-31'
) AS temp
WHERE diff = 7
GROUP BY user_id
HAVING COUNT(*) >= 7;
请确保将上述查询中的signin_table
替换为实际存储用户签到记录的表名,user_id
替换为实际的用户ID列名,date
替换为实际的日期列名。
这个查询使用了窗口函数ROW_NUMBER()
和日期差函数DATEDIFF()
来计算每个用户的签到顺序和日期差。然后,通过子查询筛选出日期差为7的记录,最后通过GROUP BY
和HAVING
子句来找到连续签到7天的用户。
这个要看你的表结构怎么定义的
一个比较好的思路是,在表结构上定义为
用户id,日期,连续签到数
然后签到的时候插入记录的时候就判断前一天是否签到,如果没有,就连续签到数归0,否则将昨日的数据+1
这样一来,查询就简单了。
表怎么写的
不知道你这个问题是否已经解决, 如果还没有解决的话:首先,根据问题描述,我们需要先创建一个表来存储用户的签到记录。假设我们的表名为sign_records
,包含以下列: - user_id
:用户ID,用于标识每个用户 - sign_date
:签到日期,用于记录用户的签到日期
我们可以使用以下SQL语句创建该表:
CREATE TABLE sign_records (
user_id INT,
sign_date DATE
);
然后,我们可以通过以下步骤来实现统计连续签到7天的用户:
SELECT
语句从sign_records
表中选择给定月份范围内的签到记录。SELECT user_id, sign_date
FROM sign_records
WHERE sign_date >= '2022-01-01' AND sign_date <= '2022-01-31';
请根据实际情况修改'2022-01-01'
和'2022-01-31'
为你所需查询的月份范围。
GROUP BY
语句按user_id
分组,并按sign_date
排序,以确保签到记录按用户和日期顺序排列。SELECT user_id, sign_date
FROM sign_records
WHERE sign_date >= '2022-01-01' AND sign_date <= '2022-01-31'
GROUP BY user_id, sign_date
ORDER BY user_id, sign_date;
CASE
语句来计算每个用户的连续签到天数。当用户的签到日期与上一条记录的签到日期相差不超过1天时,连续签到天数加1;否则,连续签到天数重新计算为1。SELECT user_id, sign_date,
(CASE
WHEN DATEDIFF(sign_date, @prev_sign_date) <= 1 THEN @consecutive_days := @consecutive_days + 1
ELSE @consecutive_days := 1
END) AS consecutive_days,
@prev_sign_date := sign_date
FROM (
SELECT user_id, sign_date
FROM sign_records
WHERE sign_date >= '2022-01-01' AND sign_date <= '2022-01-31'
GROUP BY user_id, sign_date
ORDER BY user_id, sign_date
) AS temp
CROSS JOIN (SELECT @prev_sign_date := NULL, @consecutive_days := 0) AS vars;
SELECT user_id
FROM (
SELECT user_id, sign_date,
(CASE
WHEN DATEDIFF(sign_date, @prev_sign_date) <= 1 THEN @consecutive_days := @consecutive_days + 1
ELSE @consecutive_days := 1
END) AS consecutive_days,
@prev_sign_date := sign_date
FROM (
SELECT user_id, sign_date
FROM sign_records
WHERE sign_date >= '2022-01-01' AND sign_date <= '2022-01-31'
GROUP BY user_id, sign_date
ORDER BY user_id, sign_date
) AS temp
CROSS JOIN (SELECT @prev_sign_date := NULL, @consecutive_days := 0) AS vars
) AS consecutive_days_table
WHERE consecutive_days = 7;
这个查询语句将返回在给定月份内连续签到7天的用户ID。请根据实际情况修改查询语句中的日期范围。
希望以上解决方案对你有帮助,如果还有任何问题,请随时提问。