Come interrogare tra due date usando Laravel ed Eloquent?


122

Sto cercando di creare una pagina di report che mostri i report da una data specifica a una data specifica. Ecco il mio codice attuale:

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

Quello che fa in semplice SQL è select * from table where reservation_from = $now.

Ho questa query qui ma non so come convertirla in query eloquente.

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

Come posso convertire il codice sopra in una query eloquente? Grazie in anticipo.


qual è il formato della data in reservation_from. puoi utilizzare i valori di carbonio basati su questo.
Athi Krishnan

il formato della data è TIMESTAMP @AthiKrishnan
wobsoriano

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

Risposte:


247

Il whereBetweenmetodo verifica che il valore di una colonna sia compreso tra due valori.

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

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

In alcuni casi è necessario aggiungere dinamicamente l'intervallo di date. Sulla base del commento di @Anovative puoi farlo:

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

Se desideri aggiungere più condizioni, puoi utilizzare orWhereBetween. Se desideri escludere un intervallo di date, puoi utilizzare whereNotBetween.

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

Altre clausole utili dove: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Laravel documenta le clausole Where.


Come verrebbe gestito se le $frome $tosarebbero date dinamiche che appartengono al modello? Come in c'è un effective_ate expires_atcampi e voglio interrogare per vedere se l'elemento corrente è all'interno di tale intervallo. Ho provato each()con un if che utilizza Carbon::now()->between( ... ), tuttavia restituisce ancora tutti i risultati.
Rockin4Life33

4
EDIT per il mio commento sopra: trascurato filter(), che ha funzionato. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33

1
@ Innovative grazie per il tuo utile commento. Aggiornerò la mia risposta in base al tuo commento.
Peter Kota

darà solo dalla registrazione della data.
Muhammad

1
C'è un problema con il secondo metodo. Caricherà tutti i record dal DB alla memoria e solo allora eseguirà il filtraggio.
Jino Antony,

12

Un'altra opzione se il tuo campo è datetimeinvece di date( sebbene funzioni per entrambi i casi ):

$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
tecnicamente non dovrebbe essere $ toDate. "23: 59.59.999"?
stevepowell2000

@ stevepowell2000 Dipende dal tuo database, nel mio caso memorizziamo la data con questo formato 'AAAA-MM-GG HH: MM: SS' in un campo mysql datetime, senza precisione di microsecondi. Informazioni correlate: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

Ottimo punto. Quindi, se si trattava di un campo datetime o timestamp ci possono andare tutti la via d'uscita a 23: 59: 59,999,999 mila "Un valore DATETIME o TIMESTAMP può includere una frazioni di secondo parte finale in un massimo di microsecondi (6 cifre) di precisione."
stevepowell2000

1
grazie mi hai aiutato a svolgere il mio compito prima! amo questa risposta fratello! :) -habie
Habie Smart

10

Quanto segue dovrebbe funzionare:

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

8

Se vuoi controllare se la data corrente esiste tra due date in db: => qui la query otterrà l'elenco delle applicazioni se la domanda del dipendente da e fino alla data esiste nella data odierna.

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

7

Prova questo:

Poiché stai recuperando in base al valore di una singola colonna, puoi semplificare la query allo stesso modo:

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

Recupera in base alla condizione: laravel docs

Spero che questo abbia aiutato.


6

E ho creato l'ambito del modello

Ulteriori informazioni sugli ambiti:

Codice:

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

E nel controller, aggiungi la Carbon Library all'inizio

use Carbon\Carbon;

O

use Illuminate\Support\Carbon;

Per ottenere il record degli ultimi 10 giorni da adesso

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

Per ottenere il record degli ultimi 30 giorni da adesso

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

1
WhereDateBetween second param deve essere un array.
Mkey

È solo un ambito del modello, non è il metodo Builder
Manojkiran.A

Oh sì, l'ho perso in qualche modo.
Colpa

5

Se è necessario specificare quando un campo datetime dovrebbe essere così.

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

2
Ciao, benvenuto in Stack Overflow. Quando rispondi a una domanda che ha già molte risposte, assicurati di aggiungere ulteriori informazioni sul motivo per cui la risposta che stai fornendo è sostanziale e non semplicemente riecheggia ciò che è già stato controllato dal poster originale. Ciò è particolarmente importante nelle risposte "solo codice" come quella che hai fornito.
chb

3

So che potrebbe essere una vecchia domanda, ma mi sono appena trovato in una situazione in cui ho dovuto implementare questa funzione in un'app Laravel 5.7. Di seguito è riportato ciò che ha funzionato da me.

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

Dovrai anche usare Carbon

use Carbon\Carbon;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.