如何查询近2个月到期的产品?exDate格式为YYYY-MM
解决即将到期产品查询的SQL问题
嘿,我明白你遇到的麻烦了——原SQL语句返回所有记录,核心问题是字符串类型的到期日期和日期时间类型的区间不匹配导致的隐式转换错误。
为什么原语句失效?
你的exDate是Y-m格式的字符串(比如2018-03),而NOW()返回的是完整的日期时间值(比如2024-05-20 14:30:00)。当数据库尝试把字符串和日期类型做比较时,会进行隐式类型转换,但这种转换逻辑并不符合你的预期:比如'2018-03'可能被转成'2018-03-00'(无效日期),导致区间判断失效,最终返回所有记录。
解决方案
下面提供两种可行的修复方案,优先推荐第一种长期方案:
方案1:修改字段类型(最优)
用字符串存储日期不是最佳实践,建议把exDate字段改为DATE类型(或MySQL的YEAR_MONTH类型)。如果业务中到期日是当月最后一天,可以把原字符串转成对应月份的最后一天存储(比如'2018-03'转成'2018-03-31');如果是当月第一天,就转成'2018-03-01'。
修改后,查询语句会更简洁高效:
SELECT * FROM product WHERE exDate BETWEEN DATE_FORMAT(NOW(), '%Y-%m-01') AND LAST_DAY(NOW() + INTERVAL 2 MONTH);
方案2:不修改字段,统一类型后比较
如果暂时无法修改字段类型,需要把exDate和查询区间统一成同一种类型:
方式A:将字符串转成日期类型比较
用STR_TO_DATE把exDate转成日期(默认是当月第一天),再和日期区间对比:
SELECT * FROM product WHERE STR_TO_DATE(exDate, '%Y-%m') BETWEEN DATE_FORMAT(NOW(), '%Y-%m-01') AND LAST_DAY(NOW() + INTERVAL 2 MONTH);
方式B:将日期区间转成字符串比较
把当前日期和两个月后的日期转成Y-m字符串,直接和exDate做字符串字典序比较(注意必须保证exDate格式严格为YYYY-MM):
SELECT * FROM product WHERE exDate BETWEEN DATE_FORMAT(NOW(), '%Y-%m') AND DATE_FORMAT(NOW() + INTERVAL 2 MONTH, '%Y-%m');
注意事项
- 字符串比较依赖严格的格式,如果
exDate存在2018-3(少前导零)这种格式,方式B会出错,此时优先用方式A。 - 若使用方案1,记得给
exDate字段添加索引,大幅提升查询效率。
内容的提问来源于stack exchange,提问作者SamDasti
相关产品推荐
相关产品推荐

