จะสอบถามระหว่างวันที่สองวันโดยใช้ 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

ฉันจะแปลงรหัสด้านบนเป็นแบบสอบถามที่คมชัดได้อย่างไร ขอบคุณล่วงหน้า.


รูปแบบวันที่ในรูปแบบreservation_fromใด คุณสามารถใช้ค่าคาร์บอนตามนั้น
Athi Krishnan

รูปแบบวันที่คือ TIMESTAMP @AthiKrishnan
wobsoriano

4
มันจะเป็นอย่างไรReservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get();
Athi Krishnan

คำตอบ:


248

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, ,whereExistswhereRaw

เอกสาร Laravel เกี่ยวกับ Where Clauses


สิ่งนี้จะได้รับการจัดการอย่างไรหาก$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
@ นวัตกรรมขอบคุณสำหรับความคิดเห็นที่เป็นประโยชน์ของคุณ ฉันจะอัปเดตคำตอบตามความคิดเห็นของคุณ
Peter Kota

จะให้จากบันทึกวันที่เท่านั้น
มูฮัมหมัด

1
มีปัญหากับวิธีที่สอง มันจะโหลดบันทึกทั้งหมดจากฐานข้อมูลไปยังหน่วยความจำจากนั้นจะทำการกรองเท่านั้น
Jino Antony

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 ขึ้นอยู่กับฐานข้อมูลของคุณในกรณีของฉันเราจัดเก็บวันที่ด้วยรูปแบบนี้ 'YYYY-MM-DD HH: MM: SS' ในฟิลด์ mysql datetime โดยไม่มีความแม่นยำระดับไมโครวินาที ข้อมูลที่เกี่ยวข้อง: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

จุดที่ดี ดังนั้นหากเป็นช่องวันที่เวลาหรือเวลาที่ประทับเราอาจจะไปจนถึง 23: 59: 59.999999 "ค่า DATETIME หรือ TIMESTAMP สามารถรวมเศษเสี้ยววินาทีต่อท้ายได้ในความแม่นยำไม่เกิน microseconds (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 ระหว่างพารามิเตอร์ที่สองต้องเป็นอาร์เรย์
Mkey

มันเป็นเพียงขอบเขตของโมเดลไม่ใช่วิธีการสร้าง
Manojkiran

โอ้ใช่พลาดอย่างนั้น My bad :)
Mkey

5

หากคุณจำเป็นต้องมีเมื่อฟิลด์วันที่และเวลาควรเป็นเช่นนี้

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

คุณจะต้องใช้ Carbon

use Carbon\Carbon;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.