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

MySQL查询库存3个月内到期物品问题求助(expire_date为m/Y格式)

问题分析与解决方案

核心问题:日期格式转换错误

你的代码中STR_TO_DATE的格式符使用错误,导致无法正确解析日期字符串,最终查询不到数据。

原代码里,CONCAT('01/', expire_date)会生成类似01/01/2024的字符串(假设expire_date为01/2024),但你使用的格式符%d%m/%Y要求日期部分是无分隔符的日和月(比如0101/2024),和实际生成的带斜杠的字符串不匹配,导致日期转换失败。

修正后的代码方案

方案1:修复日期格式符

调整STR_TO_DATE的格式符为%d/%m/%Y,同时优化日期计算逻辑:

// 获取当前日期(YYYY-MM-DD格式)
$currentDate = date('Y-m-d');
// 计算三个月后的日期
$threeMonthsLater = date('Y-m-d', strtotime('+3 months'));

// 修正后的SQL语句
$sql = "SELECT `medicine`.*, `supplier`.`s_id`, `s_name`
        FROM `medicine`
        LEFT JOIN `supplier` ON `medicine`.`supplier_id` = `supplier`.`s_id`
        WHERE STR_TO_DATE(CONCAT('01/', `expire_date`), '%d/%m/%Y') BETWEEN ? AND ?";

// 使用预处理语句避免SQL注入(强烈推荐)
$stmt = $pdo->prepare($sql);
$stmt->execute([$currentDate, $threeMonthsLater]);
$expiringItems = $stmt->fetchAll(PDO::FETCH_ASSOC);

方案2:按年月字符串直接比较(更高效)

既然expire_date是MM/YYYY格式,我们可以跳过日期转换,直接通过字符串拼接实现逻辑比较,性能更优:

// 获取当前年月(YYYYMM格式)
$currentYearMonth = date('Ym');
// 计算三个月后的年月(YYYYMM格式)
$threeMonthsLaterYearMonth = date('Ym', strtotime('+3 months'));

$sql = "SELECT `medicine`.*, `supplier`.`s_id`, `s_name`
        FROM `medicine`
        LEFT JOIN `supplier` ON `medicine`.`supplier_id` = `supplier`.`s_id`
        WHERE CONCAT(RIGHT(`expire_date`, 4), LEFT(`expire_date`, 2)) BETWEEN ? AND ?";

// 预处理执行
$stmt = $pdo->prepare($sql);
$stmt->execute([$currentYearMonth, $threeMonthsLaterYearMonth]);
$expiringItems = $stmt->fetchAll(PDO::FETCH_ASSOC);

这个方案把expire_date的MM/YYYY转换成YYYYMM格式的字符串(比如01/2024转为202401),直接和当前、三个月后的年月字符串比较,避免了日期转换的开销,逻辑也更可靠。

额外注意事项

  • SQL注入风险:原代码直接将变量拼入SQL语句,存在严重注入漏洞,必须使用预处理语句。
  • 字段类型优化:建议把expire_date字段从varchar改为date或yearmonth类型,后续日期操作会更高效且不易出错。

内容的提问来源于stack exchange,提问作者Chamssoudine Bacar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:42:36