递归CTE查询何时终止?连续登录天数统计的技术疑问
递归CTE自动终止的原因解答
你的理解完全正确——这个递归CTE不需要额外加WHERE子句就能正常终止,核心原因就是当递归分支的内连接没有匹配到符合条件的记录时,不会生成新的递归结果行,当所有递归分支都无法产出新行时,递归过程就自动停止了。
具体执行逻辑拆解
锚点成员(递归起点)
首先执行锚点部分:SELECT id, login_date, 1 AS days FROM Logins这一步会取出所有用户的每一条登录记录,初始连续天数
days设为1,作为递归的基础数据集。递归成员(迭代过程)
递归部分的逻辑是:SELECT l.id, l.login_date, rec_t.days+1 FROM rec_t INNER JOIN Logins l ON rec_t.id = l.id AND DATE_ADD(rec_t.login_date, INTERVAL 1 DAY) = l.login_date每一轮递归都会用上一轮
rec_t的结果,去关联Logins表,筛选出同一个用户、且登录日期正好是上一条记录次日的行。- 如果某条
rec_t的记录找不到对应的次日登录记录,内连接就不会返回任何结果,这条记录也就不会生成新的递归行; - 只有找到匹配的次日登录记录,才会生成
days+1的新行,进入下一轮递归。
- 如果某条
自动终止的触发
当某一轮递归成员完全没有产出任何新的结果行时,整个递归过程就会自动终止,因为没有新的数据可以继续迭代了。
额外优化提示
原代码中用WHERE days = 5筛选连续登录5天及以上的用户,虽然最终通过DISTINCT id能得到正确结果(连续登录超5天的用户必然会生成days=5的记录),但更严谨的写法可以直接判断连续天数达标:
SELECT * FROM Accounts WHERE id IN ( SELECT id FROM rec_t GROUP BY id HAVING MAX(days) >=5 ) ORDER BY id
内容的提问来源于stack exchange,提问作者Hassaan Anwar
相关产品推荐
相关产品推荐

