Laravel 按日期获取以前的记录(优化)

Posted

技术标签:

【中文标题】Laravel 按日期获取以前的记录(优化)【英文标题】:Laravel Get previous records by date (optimization) 【发布时间】:2020-08-12 02:43:03 【问题描述】:

我有一个带有字段的预订表:

姓名 |字符串 来自 |日期时间 到 |日期时间

我选择其中一些预订并将它们显示为列表。我还会检查之前的预订是否相隔不到 30 天。

我通过查询每个预订的前一个预订来做到这一点:

@if ($booking->previousBooking()) // Simplified version but you get the idea

底层代码:

public function previousBooking()
    
        return Booking::where('from', '<', $this->from)
            ->orderByDesc('from')
            ->first();
    

您可能已经猜到了:它为每个预订添加了一个查询。

最好的情况是急切地加载“以前的预订”(with),这样就可以像这样访问它:

$booking->previous_booking->from

有没有办法做到这一点?

约束:

我无法查询所有预订,按“from”排序,然后只获取上一个索引

【问题讨论】:

【参考方案1】:

看看 Jonathan Reinink 的 this article。您可以通过在您的 Booking 模型上模拟 previous_booking_id 来应用他的解决方案。然后添加previousBooking() 关系并使用with('previousBooking') 查询。如果您在实施方面需要任何帮助,请告诉我。

更新


将以下范围添加到您的 Booking 模型:

public function previousBooking()

    return $this->belongsTo(Booking::class);


public function scopeWithPreviousBooking($query)

    $query->addSelect(['previous_booking_id' => Booking::select('id')
        ->whereColumn('previous_booking.from', '<', 'bookings.to')
        ->orderByDesc('from')
        ->take(1)
    ])->with('previousBooking');

您现在可以使用以下方式获取所有包含之前预订 ID 的预订:

$bookings = Booking::withPreviousBooking()->get();

现在所有预订都应该有一个previous_booking_id。我们将with('previousBooking') 添加到范围的末尾,就像我们查询预订的关系一样。 Eloquent 不关心 previous_booking_id 是否在数据库中,只要它在模型中可用(我们已经通过 addSelect() 方法完成)。

您现在应该可以在视图中使用您请求的解决方案了:

$booking->previousBooking->from

注意:如果您已应用范围,则只能访问previousBooking 关系。如果没有,previous_booking_id 不可用,因此关系将为空。如果您总是想加载以前的预订,请考虑将其添加为global scope。但是,我建议只在需要的地方应用范围。

【讨论】:

你将如何模拟previous_booking_id? 我已经更新了我的答案。这应该很适合你!这是我所知道的最优化的解决方案。 好吧,我已经做到了(添加了 return $this->belongsTo(Booking::class, 'previous_booking_id');)。但是现在我每次预订都得到相同的先前预订(相同的 ID)。你知道那可能是从哪里来的吗? 问题出在子查询中。 “从”是一个日期吗?你能确保记录不都是一样的吗?尝试重写子查询以确保选择正确的先前预订 是的,找到了。我需要像这样更改表名: DB::table('Bookings AS previous_booking')->select('previous_booking.id')

以上是关于Laravel 按日期获取以前的记录(优化)的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中按日期删除重复的数据库记录

Laravel如何获取当前时间和日期值

在 laravel 中按日期获取数据

如何使用Laravel按日期分组和统计记录?

Laravel - 使用ajax获取两个日期之间的记录

Laravel 仅按日期分组并获取计数