You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
        },
        ...(其余结果省略)
    ]
}

问题原因

  1. 参数数量不匹配导致逻辑完全错误:原SQL中只有2个占位符(对应BETWEEN的两个值),但NodeJS代码传入了3个参数,第一个参数type错误替换第一个占位符,造成条件YEAR(...) BETWEEN 'STUDENTS' AND '2022-01'。MySQL将字符串隐式转为数字后,条件变为YEAR(...) BETWEEN 0 AND 202201,所有年份都满足,过滤完全失效。
  2. 日期范围过滤逻辑错误:即使参数数量正确,仅过滤年份的逻辑也无法限制月份,只能筛选出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:55:37