如何使用Laravel和Eloquent在两个日期之间查询?


122

我正在尝试创建一个报告页面,以显示从特定日期到特定日期的报告。这是我当前的代码:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', $now)->get();

这在普通SQL中的作用是select * from table where reservation_from = $now

我在这里有此查询,但我不知道如何将其转换为雄辩的查询。

SELECT * FROM table WHERE reservation_from BETWEEN '$from' AND '$to

如何将上面的代码转换为雄辩的查询?先感谢您。


中的日期格式是什么reservation_from?您可以据此使用Carbon值。
Athi Krishnan 2015年

日期格式为TIMESTAMP @AthiKrishnan
wobsoriano

4
就像Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get()
Athi Krishnan 2015年

Answers:


245

whereBetween方法验证列的值是否在两个值之间。

$from = date('2018-01-01');
$to = date('2018-05-02');

Reservation::whereBetween('reservation_from', [$from, $to])->get();

在某些情况下,您需要动态添加日期范围。根据@Anovative的评论,您可以执行以下操作:

Reservation::all()->filter(function($item) {
  if (Carbon::now->between($item->from, $item->to) {
    return $item;
  }
});

如果您想添加更多条件,则可以使用orWhereBetween。如果您想排除日期间隔,则可以使用whereNotBetween

Reservation::whereBetween('reservation_from', [$from1, $to1])
  ->orWhereBetween('reservation_to', [$from2, $to2])
  ->whereNotBetween('reservation_to', [$from3, $to3])
  ->get();

其他有用的where子句:whereInwhereNotInwhereNullwhereNotNullwhereDatewhereMonthwhereDaywhereYearwhereTimewhereColumnwhereExistswhereRaw

Laravel关于where子句的文档。


如果$from$to是属于模型的动态日期,将如何处理?如中的effective_atexpires_at字段,我想查询一下当前项目是否在该范围内。我尝试each()使用if Carbon::now()->between( ... ),但是它仍然返回所有结果。
Rockin4Life33 '19

4
编辑以上评论:忽略了filter(),就成功了。 MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33

1
@Anovative感谢您的宝贵意见。我将根据您的评论更新答案。
彼得·科塔

它只会给出日期记录。
穆罕默德

1
第二种方法有问题。它将所有记录从数据库加载到内存,然后只有它会执行过滤。
吉诺·安东尼

12

如果您的字段datetime不是,则是另一种选择date尽管这两种情况都适用):

$fromDate = "2016-10-01";
$toDate   = "2016-10-31";

$reservations = Reservation::whereRaw(
  "(reservation_from >= ? AND reservation_from <= ?)", 
  [$fromDate." 00:00:00", $toDate." 23:59:59"]
)->get();

1
从技术上讲,它不需要是$ toDate。“ 23:59.59.999”?
stevepowell2000 '18

@ stevepowell2000这取决于您的数据库,在我的情况下,我们将这种格式的日期'YYYY-MM-DD HH:MM:SS'存储在日期时间mysql字段中,而没有微秒的精度。相关信息:dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

好点。因此,如果它是日期时间或时间戳记字段,我们可能会一直进行到23:59:59.999999“ DATETIME或TIMESTAMP值可以包含尾随小数秒的部分,精度最高为微秒(6位数)。”
stevepowell2000 '18

1
谢谢您一直以来都在帮助我完成任务!爱这个答案兄弟!:) -habie
Habie Smart

10

以下应该工作:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', '>=', $now)
                           ->where('reservation_from', '<=', $to)
                           ->get();

8

如果要检查当前日期是否在db中的两个日期之间:=>如果今天的日期中存在被雇佣者的申请,则查询将获得申请列表。

$list=  (new LeaveApplication())
            ->whereDate('from','<=', $today)
            ->whereDate('to','>=', $today)
            ->get();

7

试试这个:

由于您是基于单个列值进行提取的,因此您可以同样简化查询:

$reservations = Reservation::whereBetween('reservation_from', array($from, $to))->get();

根据条件检索:laravel文档

希望这会有所帮助。


6

我已经创建了模型范围

有关范围的更多信息:

码:

   /**
     * Scope a query to only include the last n days records
     *
     * @param  \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeWhereDateBetween($query,$fieldName,$fromDate,$todate)
    {
        return $query->whereDate($fieldName,'>=',$fromDate)->whereDate($fieldName,'<=',$todate);
    }

然后在控制器中,将Carbon Library添加到顶部

use Carbon\Carbon;

要么

use Illuminate\Support\Carbon;

从现在开始获取最近10天的记录

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(10)->toDateString(),(new Carbon)->now()->toDateString() )->get();

从现在开始获取最近30天的记录

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(30)->toDateString(),(new Carbon)->now()->toDateString() )->get();

1
WhereDateBetween第二个参数需要是一个数组。
Mkey

这只是模型的范围,而不是Builder方法
Manojkiran.A

哦,是的,以某种方式错过了。我的坏事:)
Mkey

5

如果您需要在何时一个datetime字段应该是这样的。

return $this->getModel()->whereBetween('created_at', [$dateStart." 00:00:00",$dateEnd." 23:59:59"])->get();

2
嗨,欢迎来到Stack Overflow。当回答已经有很多答案的问题时,请确保对您提供的回答为何具有实质性,而不是简单地呼应原始张贴者已经审查过的内容,增加一些其他见解。这在“仅代码”答案(例如您提供的答案)中尤其重要。
chb

3

我知道这可能是一个老问题,但是我发现自己处于不得不在Laravel 5.7应用程序中实现此功能的情况。以下是我的工作方式。

 $articles = Articles::where("created_at",">", Carbon::now()->subMonths(3))->get();

您还需要使用Carbon

use Carbon\Carbon;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.