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

MySQL使用BETWEEN查询dd-mm-yyyy格式日期区间结果包含往年数据

MySQL日期区间查询返回非目标年份数据问题解决方案

问题根源

你的查询逻辑错误本质是bill_date字段使用字符串类型存储日期,而非MySQL原生DATE/DATETIME类型:字符串比较是按字符位从左到右逐一比对,不是按日期的年/月/日优先级做逻辑判断。
举个例子,字符串'16-09-2020'和左边界'15-09-2021'比对时,第二位6 > 5就会直接判定该字符串大于左边界,和右边界'23-09-2021'比对时第一位1 < 2就会判定小于右边界,最终2020年的无关数据就会被误纳入结果集。

修复方案

临时查询修复(无需修改表结构)

使用MySQL内置STR_TO_DATE函数,把字符串格式的日期统一转为原生日期类型后再做区间判断,正确查询语句如下:

SELECT * FROM `msr_bills` 
WHERE STR_TO_DATE(`bill_date`, '%d-%m-%Y') 
BETWEEN STR_TO_DATE('15-09-2021', '%d-%m-%Y') AND STR_TO_DATE('23-09-2021', '%d-%m-%Y');

注意格式符要和存储结构匹配:%d代表2位数日期,%m代表2位数月份,%Y代表4位数年份。

永久优化方案(推荐)

直接修改bill_date字段为原生DATE类型,从根源避免字符串比对的逻辑错误,同时支持索引优化查询性能,操作步骤如下:

  • 先备份全表数据,避免操作失误导致数据丢失
  • 新增临时DATE类型字段存储转换后的日期
ALTER TABLE `msr_bills` ADD COLUMN `bill_date_new` DATE;
  • 把原有字符串日期转换为DATE类型写入新字段
UPDATE `msr_bills` SET `bill_date_new` = STR_TO_DATE(`bill_date`, '%d-%m-%Y');
  • 校验新字段数据无误后,替换原有字段
ALTER TABLE `msr_bills` DROP COLUMN `bill_date`;
ALTER TABLE `msr_bills` CHANGE COLUMN `bill_date_new` `bill_date` DATE;

修改完成后,直接使用MySQL标准日期格式yyyy-mm-dd查询即可,示例:

SELECT * FROM `msr_bills` WHERE `bill_date` BETWEEN '2021-09-15' AND '2021-09-23';

补充说明

如果暂时无法修改字段类型,也可以把存储的日期字符串顺序调整为yyyy-mm-dd格式,此时字符串逐位比对的结果和日期逻辑比对结果一致,也能避免跨年份的误判问题,但性能和数据合法性校验能力仍不如原生日期类型。


内容的提问来源于stack exchange,提问作者Ram Gowda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:00:03