SQL查询需求:按ID与月份统计满足点击条件的月份数量
统计每个id满足「每月多次点击」的月份数量
你已经有了判断每个id每月是否有多次点击的基础查询,现在要进一步统计每个id有多少个这样的月份,我来给你拆解下实现步骤:
第一步:先筛选出符合条件的(id, 月份)组合
你的原查询已经能算出每个id每个月的有效点击天数(clicks>0的天数),我们只需要加上HAVING子句,过滤出那些点击天数≥2的月份:
SELECT id, MONTH(date) AS month_num FROM mydb WHERE date >= '20180101' AND date < '20180424' AND clicks > 0 GROUP BY id, MONTH(date) HAVING COUNT(id) >= 2; -- 这里COUNT(id)就是该月clicks>0的天数,≥2即满足「多次点击」
⚠️ 小提示:你的date列是字符串格式的'20180420',建议给日期值加上单引号,避免类型不匹配的问题;如果数据库支持,最好把字符串日期转成真正的日期类型来处理,比如MySQL里用STR_TO_DATE(date, '%Y%m%d'),这样日期范围判断会更准确。
第二步:统计每个id的合格月份数
把上面的查询作为子查询,再按id分组统计数量就可以了:
SELECT id, COUNT(DISTINCT month_num) AS qualified_month_count FROM ( SELECT id, MONTH(date) AS month_num FROM mydb WHERE date >= '20180101' AND date < '20180424' AND clicks > 0 GROUP BY id, MONTH(date) HAVING COUNT(id) >= 2 ) AS qualified_months GROUP BY id;
用COUNT(DISTINCT month_num)是为了确保同一个月份不会被重复统计,虽然内层分组已经保证每个id每个月只有一条记录,但加上DISTINCT会让逻辑更严谨。
可选:一步到位的写法
如果你喜欢更紧凑的逻辑,也可以用嵌套聚合直接完成统计:
SELECT id, COUNT(CASE WHEN monthly_click_days >= 2 THEN 1 END) AS qualified_month_count FROM ( SELECT id, MONTH(date) AS month_num, COUNT(id) AS monthly_click_days FROM mydb WHERE date >= '20180101' AND date < '20180424' AND clicks > 0 GROUP BY id, MONTH(date) ) AS monthly_stats GROUP BY id;
内层查询先算出每个id每个月的有效点击天数,外层用CASE语句标记出符合条件的月份,最后统计标记的数量,逻辑清晰易懂。
额外优化:更可靠的日期处理
如果你的date列是字符串类型,直接用MONTH()可能会有潜在问题,建议先转换为日期类型:
SELECT id, COUNT(DISTINCT month_num) AS qualified_month_count FROM ( SELECT id, MONTH(STR_TO_DATE(date, '%Y%m%d')) AS month_num FROM mydb WHERE STR_TO_DATE(date, '%Y%m%d') >= '2018-01-01' AND STR_TO_DATE(date, '%Y%m%d') < '2018-04-24' AND clicks > 0 GROUP BY id, MONTH(STR_TO_DATE(date, '%Y%m%d')) HAVING COUNT(id) >= 2 ) AS qualified_months GROUP BY id;
这样可以避免因为字符串格式异常导致的日期解析错误,让查询更稳定。
内容的提问来源于stack exchange,提问作者Kiriakos Papachristou
相关产品推荐
相关产品推荐

