如何优化这个雄辩的查询? (检查日期范围是不是尚未采用)

Posted

技术标签:

【中文标题】如何优化这个雄辩的查询? (检查日期范围是不是尚未采用)【英文标题】:How to optimize this eloquent query? (check that a date range is not already taken)如何优化这个雄辩的查询? (检查日期范围是否尚未采用) 【发布时间】:2022-01-06 15:01:10 【问题描述】:

这是我的 Eloquent 查询,它允许根据“started_at”和“ends_at”检查日期是否已被占用。

$bookings = Booking::where(function ($q) use ($start, $end) 
            $q->orWhere('started_at', '>=', $start)
                ->where('started_at', '<=', $end)
                ->where('status', '!==', Booking::STATUS_CANCELED);
            )
            ->orWhere(function ($q) use ($start, $end) 
                $q->where('ends_at', '>=', $start)
                    ->where('ends_at', '<=', $end)
                    ->where('status', '!==', Booking::STATUS_CANCELED);
            )
            ->orWhere(function ($q) use ($start, $end) 
                $q->where('started_at', '<', $start)
                    ->where('ends_at', '>', $end)
                    ->where('status', '!==', Booking::STATUS_CANCELED);
            )->get();

查询有效,但我觉得有点长,可以缩短。

尤其是检查状态是否“已取消”的 where。

提前致谢

【问题讨论】:

【参考方案1】:

尚未对此进行测试,但类似这样的东西应该可以工作:

$bookings = Booking::where('status', '!=', Booking::STATUS_CANCELED)
    ->where(function ($query) use ($start, $end) 
        $query->whereBetween('started_at', [$start, $end])
            ->orWhereBetween('ends_at', [$start, $end])
            ->orWhere(function ($query) use ($start, $end) 
                $query->where('started_at', '<', $start)
                    ->where('ends_at', '>', $end);
            );
    );

【讨论】:

【参考方案2】:

您的查询可能如下所示:

       $bookings = Booking::where('status', '!==', Booking::STATUS_CANCELED)
        ->where(function ($q) use ($start, $end) 
            $q->where('started_at', '<=', $end)
                ->orWhere('started_at', '>=', $start);
        )
        ->orWhere(function ($q) use ($start, $end) 
            $q->where('ends_at', '>=', $start)
                ->where('ends_at', '<=', $end);
        )->orWhere(function ($q) use ($start, $end) 
            $q->where('started_at', '<', $start)
                ->where('ends_at', '>', $end);
        )->get();

【讨论】:

我已经测试过了,还是不行

以上是关于如何优化这个雄辩的查询? (检查日期范围是不是尚未采用)的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 检查日期范围是不是在日期范围内

如何检查日期范围选择器中的日期是不是更改?

关于如何检查子表是不是具有某些多个值的雄辩或 SQL 方式

选择查询优化

Laravel 雄辩的查询 WhereNotIn 与 WhereNotNull

检查一个表中的日期是不是出现在 Access 中另一个表的范围内