求高效MySQL查询:按日期统计成功登录的唯一客户端访客数
统计每日符合条件的唯一访客数(包含无数据日期)
要实现需求,核心是先生成完整的日期序列,再和筛选后的登录数据做左连接,这样就能覆盖无符合条件访客的日期并显示计数为0。以下是适配MySQL 8.0+的高效纯SQL方案(无需额外工具):
WITH RECURSIVE date_range AS ( -- 锚点:获取数据中的最小和最大日期 SELECT MIN(DATE(date_created)) AS date_val, MAX(DATE(date_created)) AS max_date FROM your_table_name UNION ALL -- 递归生成后续日期,直到达到最大日期 SELECT DATE_ADD(date_val, INTERVAL 1 DAY), max_date FROM date_range WHERE date_val < max_date ), valid_clients AS ( -- 预处理:筛选符合条件的记录,按日期+person_id去重(同一用户同一天多次登录只算一次) SELECT DATE(date_created) AS visit_date, person_id FROM your_table_name WHERE area = 'client' AND success = 1 GROUP BY visit_date, person_id ) -- 左连接日期序列和有效访客数据,统计每日数量 SELECT dr.date_val AS date, IFNULL(COUNT(vc.person_id), 0) AS successful_clients FROM date_range dr LEFT JOIN valid_clients vc ON dr.date_val = vc.visit_date GROUP BY dr.date_val ORDER BY dr.date_val;
关键部分说明:
- 递归CTE
date_range:自动生成从数据中最早登录日期到最晚登录日期的所有连续日期,确保不会遗漏任何日期(包括像2022-06-30这种无符合条件访客的日期)。 - 子查询
valid_clients:先筛选出area=client且success=1的记录,再按日期和person_id分组去重,避免同一用户同一天多次登录被重复计数,减少后续连接的数据量提升效率。 - 最终统计:通过左连接关联日期序列和有效访客数据,用
IFNULL把无匹配日期的计数转为0,最后按日期排序得到预期结果。
替换提示:
把语句中的your_table_name替换成你实际的表名即可执行,结果将完全匹配给出的预期输出。
内容的提问来源于stack exchange,提问作者tomasz74
相关产品推荐
相关产品推荐

