Как выполнить запрос между двумя датами с помощью Laravel и Eloquent?

123

Я пытаюсь создать страницу отчета, которая отображает отчеты с определенной даты до определенной даты. Вот мой текущий код:

$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

Как преобразовать приведенный выше код в красноречивый запрос? Заранее спасибо.

wobsoriano
источник
какой формат даты в reservation_from. вы можете использовать значения углерода на основе этого.
Ати Кришнан,
формат даты: TIMESTAMP @AthiKrishnan
wobsoriano
4
это было бы как Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(),;
Ати Кришнан,

Ответы:

248

The 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();

Другие полезные статьи , где: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Laravel рассказывает о предложениях Where.

Питер Кота
источник
Как бы это было обработано, если бы $fromи $toбыли динамическими датами, принадлежащими модели? Как и в есть effective_atи expires_atполе , и я хочу , чтобы запрос , чтобы увидеть , если текущий элемент находится в пределах этого диапазона. Я пробовал each()использовать if Carbon::now()->between( ... ), но он по-прежнему возвращает все результаты.
Rockin4Life33
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
@ stevepowell2000 Это зависит от вашей базы данных, в моем случае мы сохраняем дату в формате «ГГГГ-ММ-ДД ЧЧ: ММ: СС» в поле datetime mysql без точности в микросекундах. Связанная информация: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod
Отличная точка. Так что, если это было поле datetime или timestamp, мы можем полностью перейти к 23: 59: 59.999999 «Значение DATETIME или TIMESTAMP может включать конечную дробную часть секунд с точностью до микросекунд (6 цифр)».
stevepowell2000
1
Спасибо, что помогли мне выполнить мою задачу раньше! люблю этот ответ братан! :) -habie
Хаби Смарт
10

Следующее должно работать:

$now = date('Y-m-d');
$reservations = Reservation::where('reservation_from', '>=', $now)
                           ->where('reservation_from', '<=', $to)
                           ->get();
Pᴇʜ
источник
8

Если вы хотите проверить, существует ли текущая дата между двумя датами в db: => здесь запрос получит список приложений, если приложение сотрудника от и до даты существует в сегодняшней дате.

$list=  (new LeaveApplication())
            ->whereDate('from','<=', $today)
            ->whereDate('to','>=', $today)
            ->get();
Джон
источник
7

Попробуй это:

Поскольку вы выполняете выборку на основе значения одного столбца, вы можете упростить свой запрос аналогичным образом:

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

Получение на основе условия: документы laravel

Надеюсь, это помогло.

ArtisanBay
источник
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();
Manojkiran.A
источник
1
Второй параметр WhereDateBetween должен быть массивом.
Mkey
Это просто область действия модели, а не метод Строителя
Манойкиран.А
Ах да, как-то пропустил. Моя плохая :)
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();

Вам также понадобится Углерод.

use Carbon\Carbon;
Отличный Лоуренс
источник