NodeJS+MySQL2查询中BETWEEN日期过滤失效,返回非指定月份数据
问题:MySQL日期范围过滤失效,返回非指定月份数据
在NodeJS环境中使用mysql2执行SQL查询,尝试通过BETWEEN设置日期范围过滤2022年1月至2023年2月的数据,但返回结果仍包含大量Apr、Aug等非目标月份的数据。
相关代码
SQL查询语句
SELECT u.department, YEAR(STR_TO_DATE(SUBSTRING_INDEX(tlc.time, ',', 1), '%d/%m/%y')) AS year, DATE_FORMAT(STR_TO_DATE(SUBSTRING_INDEX(tlc.time, ',', 1), '%d/%m/%y'), '%b') AS month, COUNT(*) AS event_count FROM userlibrary tlc LEFT JOIN users u ON tlc.userfullname = u.fullname WHERE u.type = 'STUDENTS' AND YEAR(STR_TO_DATE(SUBSTRING_INDEX(tlc.time, ',', 1), '%d/%m/%y')) BETWEEN ? AND ? GROUP BY u.department, year, month ORDER BY u.department, year, month;
NodeJS调用代码
const [results, fields] = await connection.query(sql, [ type, `${startYear}-${from}`, `${endYear}-${end}`, ]);
请求参数
- from: 01
- end: 02
- startYear: 2022
- endYear: 2023
错误返回结果示例
{ "results": [ { "department": "College 1", "year": 2023, "month": "Apr", "event_count": 25 }, ...(其余结果省略) ] }
问题原因
- 参数数量不匹配导致逻辑完全错误:原SQL中只有2个占位符(对应BETWEEN的两个值),但NodeJS代码传入了3个参数,第一个参数
type错误替换第一个占位符,造成条件YEAR(...) BETWEEN 'STUDENTS' AND '2022-01'。MySQL将字符串隐式转为数字后,条件变为YEAR(...) BETWEEN 0 AND 202201,所有年份都满足,过滤完全失效。 - 日期范围过滤逻辑错误:即使参数数量正确,仅过滤年份的逻辑也无法限制月份,只能筛选出2022至2023年的所有数据,无法限定1-2月。
修复方案
步骤1:修正SQL语句和参数匹配
将SQL中硬编码的u.type = 'STUDENTS'改为占位符(支持动态传入类型),同时修改WHERE条件为直接过滤完整日期范围,而非仅年份。
修复后的SQL语句
SELECT u.department, YEAR(event_date) AS year, DATE_FORMAT(event_date, '%b') AS month, COUNT(*) AS event_count FROM ( SELECT userfullname, STR_TO_DATE(SUBSTRING_INDEX(time, ',', 1), '%d/%m/%y') AS event_date FROM userlibrary ) tlc LEFT JOIN users u ON tlc.userfullname = u.fullname WHERE u.type = ? AND tlc.event_date BETWEEN ? AND ? GROUP BY u.department, year, month ORDER BY u.department, year, month;
修复后的NodeJS代码
// 构造起始日期和结束日期(自动处理闰月等情况) const startDate = `${startYear}-${from}-01`; const endDate = new Date(endYear, end, 0).toISOString().split('T')[0]; const [results, fields] = await connection.query(sql, [ type, startDate, endDate ]);
关键说明
- 日期范围正确匹配:将
tlc.time转换为标准DATE类型后,直接用BETWEEN过滤完整日期区间,确保仅返回2022-01-01至2023-02-28的数据。 - 参数数量匹配:SQL中3个占位符对应NodeJS传入的3个参数,避免参数错位导致逻辑错误。
- 性能优化:通过子查询预先转换日期,避免SELECT和WHERE中重复调用
STR_TO_DATE和SUBSTRING_INDEX,提升查询效率。
内容的提问来源于stack exchange,提问作者Stykgwar
相关产品推荐
相关产品推荐

