MySQL DATEDIFF函数异常:LeetCode 550题测试用例6不通过求助
问题分析与修正
你的代码核心逻辑错误在于分组时对followdate的处理不符合需求,导致统计结果出现偏差。
错误原因拆解
- 你的
t1CTE将每个玩家的所有登录日期与次日登录做左连接,这会产生多条同一玩家的记录(对应不同登录日期的次日情况)。 - 在
t2子查询中,按player_id分组后直接选取followdate,但MySQL在非标准分组(SELECT包含非分组且未聚合的列)时,会随机返回该分组内某一行的followdate值。这就导致你拿到的followdate可能是玩家某次非首次登录的次日,而非首次登录日期的次日。- 比如玩家89的记录中,
followdate被错误取到了2019-02-27(对应他2019-02-26的登录),而非首次登录2019-01-18的次日(若当日无登录则应为NULL),这直接导致统计时的误判。
- 比如玩家89的记录中,
修正后的代码
方法一:关联首次登录表与原表统计
WITH first_logins AS ( -- 先获取每个玩家的首次登录日期 SELECT player_id, MIN(event_date) AS first_login_date FROM Activity GROUP BY player_id ) SELECT ROUND( -- 统计首次登录次日仍登录的玩家数(去重避免重复计数) COUNT(DISTINCT fl.player_id) / -- 统计总玩家数 (SELECT COUNT(DISTINCT player_id) FROM Activity), 2 ) AS fraction FROM first_logins fl -- 关联原表,筛选出首次登录次日有登录记录的玩家 JOIN Activity a ON fl.player_id = a.player_id AND a.event_date = DATE_ADD(fl.first_login_date, INTERVAL 1 DAY);
方法二:用EXISTS更高效判断
WITH first_logins AS ( SELECT player_id, MIN(event_date) AS first_login_date FROM Activity GROUP BY player_id ) SELECT ROUND( -- 统计存在首次登录次日登录记录的玩家数 (SELECT COUNT(*) FROM first_logins fl WHERE EXISTS ( SELECT 1 FROM Activity a WHERE a.player_id = fl.player_id AND a.event_date = DATE_ADD(fl.first_login_date, INTERVAL 1 DAY) )) / -- 总玩家数 COUNT(*), 2 ) AS fraction FROM first_logins;
逻辑说明
- 先通过
first_logins准确获取每个玩家的首次登录日期,这是统计的基础。 - 核心是判断该玩家是否存在首次登录日期+1天的登录记录,而非任意登录日期的次日记录。
- 计算比例时,用符合条件的玩家数除以总玩家数,最后保留两位小数。
内容的提问来源于stack exchange,提问作者newbird_learn_DS
相关产品推荐
相关产品推荐

