MYSQLI查询中生日前后一周筛选条件无法生效的问题求助
问题分析与解决方案
你的日期筛选失效核心原因有两个:
- 字符串与日期的逻辑比较错误:
DATE_FORMAT(CURDATE(), '%m-%d')返回的是类似"10-05"的字符串,而bdate是YYYY-MM-DD格式的日期字段,MySQL会按字符串字典序而非日期逻辑比较,导致区间判断完全错误。 - 未处理跨年边界情况:比如当前是12月30日,往后7天到次年1月6日,普通区间筛选会漏掉跨年份的生日记录。
正确SQL写法(处理跨年)
推荐用将生日转换为当前/相邻年份的日期来做区间判断,确保逻辑准确:
SELECT * FROM user_birthdays WHERE ( -- 当前年的生日在前后7天内 STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY OR -- 跨年:当前年底,下一年的生日在范围内(比如12月30日→次年1月5日) STR_TO_DATE(CONCAT(YEAR(CURDATE()) + 1, '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY OR -- 跨年:当前年初,上一年的生日在范围内(比如1月5日→上一年12月30日) STR_TO_DATE(CONCAT(YEAR(CURDATE()) - 1, '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY ) AND buser_id = ?
安全优化(避免SQL注入)
直接拼接$_SESSION['id']存在SQL注入风险,改用mysqli预处理语句:
$userId = $_SESSION['id']; $sql = "SELECT * FROM user_birthdays WHERE ( STR_TO_DATE(CONCAT(YEAR(CURDATE()), '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY OR STR_TO_DATE(CONCAT(YEAR(CURDATE()) + 1, '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY OR STR_TO_DATE(CONCAT(YEAR(CURDATE()) - 1, '-', DATE_FORMAT(bdate, '%m-%d')), '%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 7 DAY AND CURDATE() + INTERVAL 7 DAY ) AND buser_id = ?"; $stmt = mysqli_prepare($connection, $sql); mysqli_stmt_bind_param($stmt, "s", $userId); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_assoc($result)) { // 处理查询结果 } }
内容的提问来源于stack exchange,提问作者humanEXE
相关产品推荐
相关产品推荐

