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

Laravel代码无法筛选19:00至次日07:00的数据,求正确实现方案

正确代码方案及问题分析

原代码问题

你当前的代码直接将start_date拼接19:00:00、end_date拼接07:00:00作为查询范围,这种逻辑仅适用于单个跨天周期(比如从10-12 19:00到10-13 07:00),但无法覆盖多个日期内的每日晚班时间段(比如10-12到10-14期间,每天19:00到次日7:00的数据),同时当end_date晚于start_date超过一天时,会漏掉中间日期的晚班数据。

解决方案一:直接筛选时间部分(简洁高效)

利用SQL的TIME()函数提取created_at的时间部分,直接判断是否属于晚班时段(19:00之后或07:00之前),同时限定日期范围:

$startDate = $request->input('start_date');
$endDate = $request->input('end_date');

$employee_qty_in_shift2 = PatrolGateSurveillanceTransaction::where('type', 1)
    ->where('client_location_id', $request->client_location_id)
    // 限定日期范围:仅查询start_date到end_date之间的记录
    ->whereDate('created_at', '>=', $startDate)
    ->whereDate('created_at', '<=', $endDate)
    // 筛选时间部分符合晚班要求的记录
    ->whereRaw("TIME(created_at) >= '19:00:00' OR TIME(created_at) <= '07:00:00'")
    ->sum('employee_qty');

dd($employee_qty_in_shift2);

优势

  • 代码简洁,性能高效(若created_at有索引,结合日期筛选能快速定位数据)
  • 自动覆盖所有日期内的晚班时段,无需处理复杂跨天逻辑

解决方案二:精确匹配跨天周期(适合特定场景)

如果你的需求是从start_date 19:00到end_date 07:00的完整跨天区间(比如统计10-12晚19点到10-14早7点的所有数据),可以用Carbon处理日期时间,拆分时间段查询:

use Carbon\Carbon;

$startDate = $request->input('start_date');
$endDate = $request->input('end_date');

$startDateTime = Carbon::parse($startDate)->setTime(19, 0, 0);
$endDateTime = Carbon::parse($endDate)->setTime(7, 0, 0);

$employee_qty_in_shift2 = PatrolGateSurveillanceTransaction::where('type', 1)
    ->where('client_location_id', $request->client_location_id)
    ->where(function ($query) use ($startDateTime, $endDateTime, $startDate, $endDate) {
        if ($startDate === $endDate) {
            // 同一天的跨天时段:当日19:00到次日07:00
            $query->whereBetween('created_at', [$startDateTime, Carbon::parse($startDate)->endOfDay()])
                ->orWhereBetween('created_at', [Carbon::parse($startDate)->addDay()->startOfDay(), $endDateTime]);
        } else {
            // 跨多天的情况,分三部分查询
            // 1. 起始日19:00到当日结束
            $query->whereBetween('created_at', [$startDateTime, Carbon::parse($startDate)->endOfDay()])
            // 2. 中间所有日期的完整晚班时段
            ->orWhere(function ($subQuery) use ($startDate, $endDate) {
                $subQuery->whereDate('created_at', '>', $startDate)
                    ->whereDate('created_at', '<', $endDate)
                    ->whereRaw("TIME(created_at) >= '19:00:00' OR TIME(created_at) <= '07:00:00'");
            })
            // 3. 结束日00:00到07:00
            ->orWhereBetween('created_at', [Carbon::parse($endDate)->startOfDay(), $endDateTime]);
        }
    })
    ->sum('employee_qty');

dd($employee_qty_in_shift2);

优势

  • 精确控制查询的时间区间,适合有特定周期要求的场景
  • 用Carbon处理日期时间,避免字符串拼接的格式错误

内容的提问来源于stack exchange,提问作者stackover flow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:01:16