Jak wyszukiwać między dwiema datami za pomocą Laravel i Eloquent?


122

Próbuję utworzyć stronę raportu, która pokazuje raporty od określonej daty do określonej daty. Oto mój obecny kod:

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

To, co to robi w zwykłym SQL, to select * from table where reservation_from = $now.

Mam tutaj to zapytanie, ale nie wiem, jak zamienić je na zapytanie elokwentne.

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

Jak mogę przekonwertować powyższy kod na elokwentne zapytanie? Z góry dziękuję.


jaki jest format daty reservation_from. możesz na tej podstawie użyć wartości węgla.
Athi Krishnan

format daty to TIMESTAMP @AthiKrishnan
wobsoriano

4
byłoby jak Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(),;
Athi Krishnan

Odpowiedzi:


247

Te whereBetweenmetody sprawdza, czy wartość kolumną jest pomiędzy dwiema wartościami.

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

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

W niektórych przypadkach musisz dynamicznie dodawać zakres dat. Na podstawie komentarza @Anovative możesz to zrobić:

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

Jeśli chcesz dodać więcej warunku, możesz użyć orWhereBetween. Jeśli chcesz wykluczyć przedział dat, możesz użyć whereNotBetween.

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

Pozostałe klauzule użyteczne gdzie: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Laravel dokumentuje o Where Clauses.


Jak by to wyglądało, gdyby dynamiczne daty należące do modelu były $fromi $tobyłyby? Jak w istnieje effective_ati expires_atpola i chcę do zapytania, czy bieżący element jest w tym przedziale. Próbowałem each()z if that uses Carbon::now()->between( ... ), jednak nadal zwraca wszystkie wyniki.
Rockin4Life33

4
EDYCJA dla mojego powyższego komentarza: przeoczony filter(), to załatwiło sprawę. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33

1
@ Innowacyjne dzięki za przydatny komentarz. Zaktualizuję moją odpowiedź na podstawie Twojego komentarza.
Peter Kota,

da tylko od daty zapisu.
Muhammad

1
Jest problem z drugą metodą. Załaduje wszystkie rekordy z bazy danych do pamięci i tylko wtedy wykona filtrowanie.
Jino Antony

12

Inna opcja, jeśli twoje pole jest datetimezamiast date( chociaż działa w obu przypadkach ):

$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
z technicznego punktu widzenia nie musiałoby to być $ toDate. 23: 59,59,999?
stevepowell2000

@ stevepowell2000 To zależy od Twojej bazy danych, w moim przypadku przechowujemy datę w formacie „RRRR-MM-DD GG: MM: SS” w polu mysql datetime, bez dokładności do mikrosekund. Powiązane informacje: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

Świetna uwaga. Więc jeśli to pole datetime lub timestamp my może przejść całą drogę do 23: 59: 59,999999 „datetime lub TIMESTAMP wartość może zawierać tylną część ułamków sekund do maksymalnie mikrosekund (6 cyfr) Precyzja”.
stevepowell2000

1
dziękuję, że pomogłeś mi wcześniej wykonać moje zadanie! Uwielbiam tę odpowiedź brachu! :) -habie
Habie Smart

10

Powinno działać:

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

8

Jeśli chcesz sprawdzić, czy aktualna data istnieje między dwiema datami w db: => tutaj zapytanie spowoduje wyświetlenie listy aplikacji, jeśli aplikacja pracownika od i do tej daty istnieje w dzisiejszej dacie.

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

7

Spróbuj tego:

Ponieważ pobierasz na podstawie wartości pojedynczej kolumny, możesz również uprościć zapytanie:

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

Pobieranie na podstawie warunku: laravel docs

Mam nadzieję, że to pomogło.


6

I stworzyłem zakres modelu

Więcej o zakresach:

Kod:

   /**
     * 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);
    }

W kontrolerze dodaj bibliotekę węgla do góry

use Carbon\Carbon;

LUB

use Illuminate\Support\Carbon;

Aby uzyskać rekord z ostatnich 10 dni od teraz

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

Aby uzyskać rekord z ostatnich 30 dni od teraz

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

1
WhereDateBetween drugi parametr musi być tablicą.
Mkey

To tylko zakres modelu, a nie metoda Buildera
Manojkiran.

O tak, jakoś to przegapiłem. Mój zły :)
Mkey

5

Jeśli potrzebujesz określić, kiedy pole daty i godziny powinno być takie.

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

2
Cześć, witaj w Stack Overflow. Odpowiadając na pytanie, na które jest już wiele odpowiedzi, pamiętaj o dodaniu dodatkowego wglądu w to, dlaczego udzielona przez Ciebie odpowiedź jest merytoryczna, a nie po prostu odzwierciedlająca to, co zostało już sprawdzone przez oryginalny plakat. Jest to szczególnie ważne w przypadku odpowiedzi „tylko kod”, takich jak ta, którą podałeś.
chb

3

Wiem, że to może być stare pytanie, ale właśnie znalazłem się w sytuacji, w której musiałem zaimplementować tę funkcję w aplikacji Laravel 5.7. Poniżej jest to, co zadziałało ode mnie.

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

Będziesz także musiał użyć węgla

use Carbon\Carbon;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.