MySQL查询问题:计算近30天各语言内容占比无返回结果
解决MySQL查询返回0行及语言占比统计问题
问题原因分析
日期格式不兼容
你的ds字段是mm/dd/yyyy的文本格式,而CURDATE()返回的是yyyy-mm-dd类型的日期,直接用BETWEEN进行范围比较时,文本与日期类型的匹配逻辑会导致筛选不到任何数据。另外你需求是统计近30天,但SQL中错误使用了INTERVAL 7 DAY,缩小了时间范围。占比统计逻辑错误
原SQL用COUNT(job_id)作为分母,这会包含所有事件(包括skip)的记录,不符合你“仅包含transfer和decision事件”的统计要求,分母应该是符合条件的总记录数。
修正后的查询语句
方法一:子查询计算总记录数
SELECT language, ROUND(100.0 * COUNT(*) / total.total_count, 2) AS percentage_share FROM job_data CROSS JOIN ( SELECT COUNT(*) AS total_count FROM job_data WHERE STR_TO_DATE(ds, '%m/%d/%Y') BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND CURDATE() AND event IN ('transfer', 'decision') ) AS total WHERE STR_TO_DATE(ds, '%m/%d/%Y') BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND CURDATE() AND event IN ('transfer', 'decision') GROUP BY language, total.total_count;
方法二:窗口函数简化计算(MySQL 8.0+支持)
SELECT language, ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 2) AS percentage_share FROM job_data WHERE STR_TO_DATE(ds, '%m/%d/%Y') BETWEEN DATE_SUB(CURDATE(), INTERVAL 30 DAY) AND CURDATE() AND event IN ('transfer', 'decision') GROUP BY language;
关键修改说明
- 日期转换:使用
STR_TO_DATE(ds, '%m/%d/%Y')将文本格式的日期转换为MySQL可识别的日期类型,确保时间范围筛选生效。 - 时间范围修正:将
INTERVAL 7 DAY改为INTERVAL 30 DAY,匹配你“近30天”的统计需求。 - 占比逻辑调整:分母改为所有符合条件(近30天+指定事件)的记录总数,分子为各语言的对应记录数,保证占比计算准确。
- 窗口函数优化:方法二利用窗口函数
SUM(COUNT(*)) OVER ()直接计算分组后的总记录数,代码更简洁高效。
内容的提问来源于stack exchange,提问作者user3895786
相关产品推荐
相关产品推荐

