Bagaimana cara menanyakan antara dua tanggal menggunakan Laravel dan Eloquent?

122

Saya mencoba membuat halaman laporan yang menampilkan laporan dari tanggal tertentu hingga tanggal tertentu. Ini kode saya saat ini:

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

Apa yang dilakukannya di SQL biasa adalah select * from table where reservation_from = $now.

Saya memiliki kueri ini di sini, tetapi saya tidak tahu cara mengubahnya menjadi kueri yang fasih.

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

Bagaimana cara mengubah kode di atas menjadi kueri yang fasih? Terima kasih sebelumnya.

wobsoriano.dll
sumber
dalam format tanggal apa reservation_from. Anda dapat menggunakan nilai Karbon berdasarkan itu.
Athi Krishnan
format tanggal adalah TIMESTAMP @AthiKrishnan
wobsoriano
4
itu akan menjadi seperti Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get(),;
Athi Krishnan

Jawaban:

247

The whereBetweenMetode memverifikasi bahwa nilai kolom adalah antara dua nilai.

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

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

Dalam beberapa kasus, Anda perlu menambahkan rentang tanggal secara dinamis. Berdasarkan komentar @Anovative , Anda dapat melakukan ini:

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

Jika Anda ingin menambahkan lebih banyak kondisi maka Anda dapat menggunakan orWhereBetween. Jika Anda ingin mengecualikan interval tanggal maka Anda dapat menggunakan whereNotBetween.

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

Klausul yang berguna di mana lain: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Laravel mendokumentasikan tentang Where Clauses.

Peter Kota
sumber
Bagaimana hal ini akan ditangani jika $fromdan $toakan menjadi tanggal dinamis yang dimiliki model? Seperti dalam ada effective_atdan expires_atladang dan saya ingin query untuk melihat apakah item saat ini berada dalam kisaran tersebut. Saya mencoba each()dengan jika itu menggunakan Carbon::now()->between( ... ), namun tetap mengembalikan semua hasil.
Rockin4Life33
4
EDIT untuk komentar saya di atas: Terabaikan filter(), itu berhasil. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33
1
@Anovative terima kasih atas komentar berguna Anda. Saya akan memperbarui jawaban saya berdasarkan komentar Anda.
Peter Kota
itu hanya akan diberikan dari catatan tanggal.
Muhammad
1
Ada masalah dengan metode kedua. Ini akan memuat semua catatan dari DB ke memori dan kemudian hanya itu yang akan melakukan penyaringan.
Jino Antony
12

Opsi lain jika bidang Anda adalah datetimealih-alih date( meskipun berfungsi untuk kedua kasus ):

$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();
tomloprod.dll
sumber
1
secara teknis tidak perlu $ toDate. "23: 59.59.999"?
stevepowell2000
@ stevepowell2000 Tergantung pada database Anda, dalam kasus saya, kami menyimpan tanggal dengan format ini 'YYYY-MM-DD HH: MM: SS' dalam bidang mysql datetime, tanpa presisi mikrodetik. Info terkait: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod
Poin yang bagus. Jadi, jika itu adalah bidang tanggal waktu atau stempel waktu, kami mungkin akan beralih sepenuhnya ke 23: 59: 59.999999 "Nilai DATETIME atau TIMESTAMP dapat menyertakan bagian detik pecahan tambahan dalam presisi hingga mikrodetik (6 digit)."
stevepowell2000
1
terima kasih Anda telah membantu saya untuk melakukan tugas saya sebelumnya! suka jawaban ini bro! :) -habie
Habie Smart
10

Berikut ini seharusnya bekerja:

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

Jika Anda ingin memeriksa apakah tanggal sekarang ada di antara dua tanggal di db: => di sini query akan mendapatkan daftar aplikasi jika aplikasi karyawan dari dan ke tanggal ada di tanggal hari ini.

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

Coba ini:

Karena Anda mengambil berdasarkan satu nilai kolom, Anda juga dapat menyederhanakan kueri Anda:

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

Ambil berdasarkan kondisi: laravel docs

Semoga ini bisa membantu.

ArtisanBay
sumber
6

Dan saya telah membuat ruang lingkup model

Lebih lanjut tentang cakupan:

Kode:

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

Dan di pengontrol, tambahkan Perpustakaan Karbon ke atas

use Carbon\Carbon;

ATAU

use Illuminate\Support\Carbon;

Untuk mendapatkan rekor 10 hari terakhir dari sekarang

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

Untuk mendapatkan rekor 30 hari terakhir dari sekarang

 $lastTenDaysRecord = ModelName::whereDateBetween('created_at',(new Carbon)->subDays(30)->toDateString(),(new Carbon)->now()->toDateString() )->get();
Manojkiran.A
sumber
1
Parameter whereDateBetween kedua harus berupa array.
Mkey
Ini hanya ruang lingkup model, itu bukan metode Builder
Manojkiran.
Oh ya, entah bagaimana melewatkannya. Saya buruk :)
Mkey
5

Jika perlu di saat harus ada bidang datetime seperti ini.

return $this->getModel()->whereBetween('created_at', [$dateStart." 00:00:00",$dateEnd." 23:59:59"])->get();
MIGUEL LOPEZ ARIZA
sumber
2
Hai, selamat datang di Stack Overflow. Saat menjawab pertanyaan yang sudah memiliki banyak jawaban, pastikan untuk menambahkan beberapa wawasan tambahan tentang mengapa tanggapan yang Anda berikan bersifat substantif dan tidak hanya menggemakan apa yang sudah diperiksa oleh pembuat poster asli. Ini terutama penting dalam jawaban "hanya kode" seperti yang Anda berikan.
chb
3

Saya tahu ini mungkin pertanyaan lama tetapi saya baru saja menemukan diri saya dalam situasi di mana saya harus menerapkan fitur ini di aplikasi Laravel 5.7. Di bawah ini adalah apa yang berhasil dari saya.

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

Anda juga perlu menggunakan Karbon

use Carbon\Carbon;
Lawrence yang luar biasa
sumber