Як робити запит між двома датами, використовуючи 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. ви можете використовувати значення вуглецю на основі цього.
Аті Крішнан

Формат дати - TIMESTAMP @AthiKrishnan
wobsoriano

4
це було б як Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get();
Аті Крішнан

Відповіді:


247

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 про Де клаузи.


Як би це вирішувалося, якщо б $fromі $toбули динамічні дати, що належать до моделі? Так як в полях є effective_atі, expires_atі я хочу запитати, чи не знаходиться поточний елемент у цьому діапазоні. Я спробував each(), якщо це використовує Carbon::now()->between( ... ), але він все одно повертає всі результати.
Rockin4Life33

4
EDIT для мого вище коментаря: Не помічено 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 Це залежить від вашої бази даних, в моєму випадку ми зберігаємо дату в такому форматі "РРРР-ММ-DD HH: MM: SS" у полі mysql дати, без точності мікросекунд. Інформація про те: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

Чудова точка. Отже, якщо це було поле дати або часової позначки, ми можемо пройти весь шлях до 23: 59: 59.999999 "Значення DATETIME або TIMESTAMP може включати в себе детальну частку секундних секунд з точністю до мікросекунд (6 цифр)."
stevepowell2000

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
WhereDateBet between second param повинен бути масивом.
Міккей

Це просто сфера моделі, це не метод Builder
Manojkiran.A

О так, це якось пропустили. Мої погані :)
Міккі

5

Якщо вам потрібно вказати, коли поле для дати має бути таким.

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

2
Привіт, Ласкаво просимо до Stack Overflow. Відповідаючи на запитання, на яке вже є багато відповідей, будь ласка, не забудьте додати трохи додаткового розуміння того, чому відповідь, яку ви надаєте, є суттєвою, а не просто повторює те, що вже було перевірено оригінальним плакатом. Це особливо важливо у відповідях "лише для коду", таких як той, який ви надали.
чб

3

Я знаю, що це може бути старим питанням, але я просто опинився в ситуації, коли мені довелося реалізувати цю функцію в додатку Laravel 5.7. Нижче - те, що працювало у мене.

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

Вам також потрібно буде використовувати Carbon

use Carbon\Carbon;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.