如何用SQL统计按顺序浏览rule2、rule3且无其他页面的用户数
问题解决方案
一、核心前提说明
要判断页面浏览顺序,你的表必须包含能确定浏览先后的字段(比如visit_time访问时间、view_order浏览序号),否则无法准确判断用户的浏览顺序。以下示例均假设表中存在visit_time字段(datetime类型,记录用户访问页面的时间)。
二、统计符合条件的用户数量
你的原SQL仅筛选了浏览过rule2或rule3的用户,完全没考虑顺序和连续性,所以不满足需求。正确的实现可以用窗口函数LEAD()来定位每个用户的下一条浏览记录:
SELECT COUNT(DISTINCT id) AS qualified_user_count FROM ( SELECT id, name_page, -- 按用户分组、访问时间排序,获取当前记录的下一个页面 LEAD(name_page) OVER (PARTITION BY id ORDER BY visit_time) AS next_page FROM DocumentationBook ) AS user_views -- 筛选当前页面是rule2且下一个页面直接是rule3的记录 WHERE name_page = 'rule2' AND next_page = 'rule3';
如果你的表没有时间字段,仅能依赖插入顺序(不推荐生产环境使用),可以先为每个用户的浏览记录生成序号,再关联查询:
-- 先为每条记录生成用户内的浏览序号 WITH user_view_order AS ( SELECT id, name_page, ROW_NUMBER() OVER (PARTITION BY id ORDER BY (SELECT NULL)) AS view_seq FROM DocumentationBook ) SELECT COUNT(DISTINCT t1.id) AS qualified_user_count FROM user_view_order t1 JOIN user_view_order t2 ON t1.id = t2.id AND t2.name_page = 'rule3' AND t2.view_seq = t1.view_seq + 1 WHERE t1.name_page = 'rule2';
三、展示用户页面浏览顺序
要直观展示每个用户的页面浏览顺序,可以用字符串聚合函数按时间排序后拼接页面名称:
MySQL 实现
SELECT id, GROUP_CONCAT(name_page ORDER BY visit_time SEPARATOR ' → ') AS browse_sequence FROM DocumentationBook GROUP BY id;
PostgreSQL 实现
SELECT id, STRING_AGG(name_page, ' → ' ORDER BY visit_time) AS browse_sequence FROM DocumentationBook GROUP BY id;
SQL Server 实现
SELECT id, STRING_AGG(name_page, ' → ') WITHIN GROUP (ORDER BY visit_time) AS browse_sequence FROM DocumentationBook GROUP BY id;
执行后会得到类似结果:
| id | browse_sequence |
|---|---|
| 1 | rule1 → rule3 |
| 2 | rule2 → rule3 |
| 3 | rule2 → rule3 |
内容的提问来源于stack exchange,提问作者Nnemune
相关产品推荐
相关产品推荐

