如何用SQL统计日志表中仅出现一次的特定年龄用户数
解决方案
核心思路
要实现同一用户仅统计一次的目标,需先锁定符合条件的用户(仅登录1次、年龄匹配区间、登录日期达标),再按年龄区间统计用户数量——核心是基于用户维度统计,而非登录记录维度。
修正后的查询语句
SELECT COUNT(CASE WHEN age BETWEEN 0 AND 18 THEN 1 END) AS "18", COUNT(CASE WHEN age BETWEEN 19 AND 30 THEN 1 END) AS "30", COUNT(CASE WHEN age BETWEEN 31 AND 50 THEN 1 END) AS "50" FROM ( -- 筛选登录日期≤2022-10-29且仅登录1次的用户ID SELECT card_id FROM logs WHERE login <= '2022-10-29' GROUP BY card_id HAVING COUNT(login) = 1 ) AS login_once_users -- 关联会员表获取用户年龄 JOIN ( SELECT card_id, DATE_PART('year', AGE(birthdate)) AS age FROM members ) AS member_ages ON login_once_users.card_id = member_ages.card_id;
关键修正点说明
- 锁定单次登录用户:内层子查询
login_once_users通过GROUP BY card_id + HAVING COUNT(login)=1,确保每个用户仅被筛选一次,从根源避免重复统计。 - 独立计算年龄:单独提取会员年龄数据,避免重复关联表带来的冗余计算。
- 按用户维度统计:外层查询通过
CASE WHEN分类年龄区间,用COUNT统计符合条件的用户数,因每个用户ID仅出现一次,不会出现重复计数。
原查询问题分析
原查询多次关联logs表且按login字段分组,导致每条登录记录都被单独统计,这是同一用户被重复计数的核心原因。
内容的提问来源于stack exchange,提问作者FaFa
相关产品推荐
相关产品推荐

