如何不使用日期对象仅用日期字符串查询数据库一周内的所有记录
原有代码返回空结果的核心原因
- 字符串比较逻辑完全错配
你数据库中存储的start_date、end_date为d/m/Y顺序的纯字符串,这类格式的字符串无法直接通过>=、<=运算符做大小比较。举个直观的例子:字符串"05/01/2024"(2024年1月5日)和"04/12/2024"(2024年12月4日)逐位比较时,"04/12/2024"的首字符为'0'、次字符为'4',会被判定为小于"05/01/2024",但真实日期中12月4日比1月5日晚了近一年,比较逻辑完全颠倒,自然无法正确匹配到结果。 - 查询区间的条件过于严格
你当前编写的start_date >= 本周起始 且 end_date <= 本周结束条件,仅能捞出整个记录的时间范围完全被包裹在本周区间内的数据。只要单条记录的时间范围和本周有任何重叠——比如记录从上周开始持续到下周、记录结束在本周中段、记录从本周初开始持续到下月——都会被这个条件遗漏。
适配现有存储规则的修正方案
不需要修改数据库的字符串存储格式,也不需要将拉取的每条记录转换为日期对象做内存过滤,只需要做两处调整即可:
- 统一比较的格式基准:在SQL查询层通过字符串转换函数,将库中存储的
d/m/Y格式日期转换为可正常排序的标准日期格式做匹配 - 替换为区间重叠的通用判断逻辑:两个时间段存在交集的充要条件是「记录的开始日期 <= 本周区间结束日」 且 「记录的结束日期 >= 本周区间开始日」
修正后的参考代码:
// 保持原有逻辑计算的周范围边界,按需替换为自然周的周一、周日即可 $weekStart = Carbon::now()->startOfDay()->format('Y-m-d'); $weekEnd = Carbon::now()->addDays(7)->endOfDay()->format('Y-m-d'); $holidays = Holiday::whereRaw( "STR_TO_DATE(start_date, '%d/%m/%Y') <= ? AND STR_TO_DATE(end_date, '%d/%m/%Y') >= ?", [$weekEnd, $weekStart] )->get();
说明:上述SQL层的转换逻辑不会修改数据库中已存储的字符串内容,全程仅做匹配时的格式适配,完全符合不使用数据库日期字段类型、仅通过日期字符串做匹配的要求,同时能覆盖所有和本周范围有重叠的记录,不会遗漏跨周的长周期数据。
内容的提问来源于stack exchange,提问作者Perry
相关产品推荐
相关产品推荐

