欢迎光临上海市救护车出租网
详情描述

1. 自连接方案(适用于小数据量)

-- 查询连续3天登录的用户(方案1)
SELECT DISTINCT a.user_id
FROM login_log a
JOIN login_log b ON a.user_id = b.user_id
    AND b.login_date = DATE_ADD(a.login_date, INTERVAL 1 DAY)
JOIN login_log c ON a.user_id = c.user_id
    AND c.login_date = DATE_ADD(a.login_date, INTERVAL 2 DAY);

-- 方案2:使用窗口函数(推荐)
SELECT DISTINCT user_id
FROM (
    SELECT 
        user_id,
        login_date,
        DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) as diff
    FROM (
        SELECT DISTINCT user_id, login_date 
        FROM login_log
    ) t
) t2
GROUP BY user_id, diff
HAVING COUNT(*) >= 3;

2. 窗口函数方案(最常用且高效)

-- 方案1:使用ROW_NUMBER计算连续登录
WITH login_days AS (
    SELECT 
        user_id,
        login_date,
        ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) as rn
    FROM (
        SELECT DISTINCT user_id, DATE(login_time) as login_date
        FROM login_log
    ) t
)
SELECT DISTINCT user_id
FROM (
    SELECT 
        user_id,
        DATE_SUB(login_date, INTERVAL rn DAY) as group_date
    FROM login_days
) t
GROUP BY user_id, group_date
HAVING COUNT(*) >= 3;

-- 方案2:使用LAG函数
WITH consecutive_check AS (
    SELECT 
        user_id,
        login_date,
        LAG(login_date, 2) OVER (PARTITION BY user_id ORDER BY login_date) as prev_date2
    FROM (
        SELECT DISTINCT user_id, DATE(login_time) as login_date
        FROM login_log
    ) t
)
SELECT DISTINCT user_id
FROM consecutive_check
WHERE DATEDIFF(login_date, prev_date2) = 2;

3. 变量方案(MySQL特定)

-- 使用用户变量追踪连续天数
SELECT DISTINCT user_id
FROM (
    SELECT 
        user_id,
        login_date,
        @seq := IF(@prev_user = user_id AND DATEDIFF(login_date, @prev_date) = 1, @seq + 1, 1) as seq,
        @max_seq := IF(@seq > @max_seq, @seq, @max_seq) as max_seq,
        @prev_user := user_id,
        @prev_date := login_date
    FROM (
        SELECT DISTINCT user_id, DATE(login_time) as login_date
        FROM login_log
        ORDER BY user_id, login_date
    ) t
    CROSS JOIN (SELECT @prev_user := NULL, @prev_date := NULL, @seq := 0, @max_seq := 0) vars
) t2
WHERE max_seq >= 3;

4. 完整的通用解决方案

-- 查询连续N天登录的用户(通用版本)
WITH daily_login AS (
    -- 去重,确保每天只算一次登录
    SELECT DISTINCT 
        user_id,
        DATE(login_time) as login_date
    FROM login_log
),
login_groups AS (
    -- 计算连续登录分组
    SELECT 
        user_id,
        login_date,
        DATE_SUB(login_date, 
                INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY
        ) as group_id
    FROM daily_login
),
consecutive_counts AS (
    -- 统计每组连续登录天数
    SELECT 
        user_id,
        group_id,
        MIN(login_date) as start_date,
        MAX(login_date) as end_date,
        COUNT(*) as consecutive_days,
        GROUP_CONCAT(login_date ORDER BY login_date) as login_dates
    FROM login_groups
    GROUP BY user_id, group_id
)
-- 查询连续N天登录的用户
SELECT DISTINCT user_id
FROM consecutive_counts
WHERE consecutive_days >= 3  -- N = 3
ORDER BY user_id;

-- 如果需要查看更多信息
SELECT *
FROM consecutive_counts
WHERE consecutive_days >= 3
ORDER BY user_id, start_date;

5. 扩展功能:查找最长连续登录天数

-- 查找每个用户的最长连续登录天数
WITH daily_login AS (
    SELECT DISTINCT user_id, DATE(login_time) as login_date
    FROM login_log
),
login_groups AS (
    SELECT 
        user_id,
        login_date,
        DATE_SUB(login_date, 
                INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY
        ) as group_id
    FROM daily_login
),
consecutive_counts AS (
    SELECT 
        user_id,
        COUNT(*) as consecutive_days,
        MIN(login_date) as start_date,
        MAX(login_date) as end_date
    FROM login_groups
    GROUP BY user_id, group_id
)
SELECT 
    user_id,
    MAX(consecutive_days) as max_consecutive_days
FROM consecutive_counts
GROUP BY user_id
ORDER BY max_consecutive_days DESC;

6. 考虑日期中断的解决方案

-- 允许中断1天的连续登录(例如:周一到周三,跳过周二也算连续)
WITH daily_login AS (
    SELECT DISTINCT user_id, DATE(login_time) as login_date
    FROM login_log
),
login_sequence AS (
    SELECT 
        user_id,
        login_date,
        LAG(login_date) OVER (PARTITION BY user_id ORDER BY login_date) as prev_date
    FROM daily_login
),
login_gaps AS (
    SELECT 
        user_id,
        login_date,
        CASE 
            WHEN prev_date IS NULL THEN 1
            WHEN DATEDIFF(login_date, prev_date) <= 2 THEN 0  -- 允许中断1天
            ELSE 1
        END as new_group
    FROM login_sequence
),
login_groups AS (
    SELECT 
        user_id,
        login_date,
        SUM(new_group) OVER (PARTITION BY user_id ORDER BY login_date) as group_id
    FROM login_gaps
)
SELECT DISTINCT user_id
FROM (
    SELECT 
        user_id,
        group_id,
        COUNT(*) as consecutive_days
    FROM login_groups
    GROUP BY user_id, group_id
    HAVING COUNT(*) >= 3
) t;

性能优化建议

建立索引

CREATE INDEX idx_user_login ON login_log(user_id, login_time);
CREATE INDEX idx_date ON login_log(login_time);

预先去重:在子查询中使用DISTINCT减少处理数据量

分区表:如果数据量大,考虑按日期分区

物化视图:对于频繁查询,可以创建物化视图存储每日活跃用户

注意事项

确保登录时间字段为日期时间类型 考虑时区问题 处理NULL值和重复数据 根据实际业务需求调整"连续"的定义(是否允许跨天等)

推荐使用窗口函数方案,它在现代数据库系统中性能最好,代码也最简洁。

相关帖子
上海市模版网站制作%小视频营销推广,收费透明
上海市模版网站制作%小视频营销推广,收费透明
为什么有些人看不懂地图或立体几何?这可能反映了哪种认知特点?
为什么有些人看不懂地图或立体几何?这可能反映了哪种认知特点?
上海市网站定制公司&网站设计与开发,定制开发
上海市网站定制公司&网站设计与开发,定制开发
在家轻松制作大餐,如何巧妙利用预制菜进行二次创作?
在家轻松制作大餐,如何巧妙利用预制菜进行二次创作?
上海市私人救护车跨省转运租车-跨省转院服务
上海市私人救护车跨省转运租车-跨省转院服务
科技玩具日益普及,它们对儿童认知发展与社交能力究竟有何影响?
科技玩具日益普及,它们对儿童认知发展与社交能力究竟有何影响?
楚雄跨省救护车出租-私人救护车电话
楚雄跨省救护车出租-私人救护车电话
运城市企业网站开发建设%购物网站开发建设,专业建站
运城市企业网站开发建设%购物网站开发建设,专业建站
包头市120救护车转院转运回家|长途120救护车护送,24小时在线电话
包头市120救护车转院转运回家|长途120救护车护送,24小时在线电话
淮南市网站搭建%软件系统开发,高端网站开发设计
淮南市网站搭建%软件系统开发,高端网站开发设计
古代民间流传的日用类书,为当时普通家庭的生活提供了哪些实用指南?
古代民间流传的日用类书,为当时普通家庭的生活提供了哪些实用指南?
如果因为身份证过期影响了重要事务,有什么应急的解决办法吗?
如果因为身份证过期影响了重要事务,有什么应急的解决办法吗?
呼和浩特市救护车长途转运病人|救护车一次多少钱
呼和浩特市救护车长途转运病人|救护车一次多少钱
新兴的宠物专车接送服务与传统托运相比,提供了哪些不同的体验和保障?
新兴的宠物专车接送服务与传统托运相比,提供了哪些不同的体验和保障?
文山120救护车出租公司-医疗转运车租赁电话
文山120救护车出租公司-医疗转运车租赁电话
江门市商城建设&专业网站建设设计,一站式建站服务
江门市商城建设&专业网站建设设计,一站式建站服务
连云港市网站开发服务%短视频营销推广,优秀设计团队
连云港市网站开发服务%短视频营销推广,优秀设计团队
怒江120救护车长途跨省运送病人|急救车长途转运
怒江120救护车长途跨省运送病人|急救车长途转运
丽江市私人长途救护车出租护送病人转院-急救车出租咨询电话,按公里收费
丽江市私人长途救护车出租护送病人转院-急救车出租咨询电话,按公里收费
针对儿童和青少年使用的电话卡,家长管控功能发展到了何种程度?
针对儿童和青少年使用的电话卡,家长管控功能发展到了何种程度?