Làm cách nào để truy vấn giữa hai ngày bằng Laravel và Eloquent?


122

Tôi đang cố gắng tạo một trang báo cáo hiển thị các báo cáo từ một ngày cụ thể đến một ngày cụ thể. Đây là mã hiện tại của tôi:

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

Điều này thực hiện trong SQL thuần túy là gì select * from table where reservation_from = $now.

Tôi có truy vấn này ở đây nhưng tôi không biết làm thế nào để chuyển đổi nó thành truy vấn hùng hồn.

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

Làm cách nào để chuyển đổi đoạn mã trên thành một truy vấn hùng hồn? Cảm ơn bạn trước.


định dạng ngày là gì reservation_from. bạn có thể sử dụng các giá trị Carbon dựa trên đó.
Athi Krishnan

định dạng ngày là dấu thời gian @AthiKrishnan
wobsoriano

4
nó sẽ như thế nào , Reservation::where('reservation_from', '>=', Carbon::createFromDate(1975, 5, 21);) ->where('reservation_from', '<=', Carbon::createFromDate(2015, 5, 21);)->get();
Athi Krishnan

Câu trả lời:


245

Các whereBetweenthẩm tra phương pháp mà giá trị của một cột là giữa hai giá trị.

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

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

Trong một số trường hợp, bạn cần thêm động phạm vi ngày. Dựa trên nhận xét của @Anovative , bạn có thể làm điều này:

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

Nếu bạn muốn thêm điều kiện thì bạn có thể sử dụng orWhereBetween. Nếu bạn muốn loại trừ khoảng thời gian ngày thì bạn có thể sử dụng whereNotBetween.

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

Khoản hữu ích nơi khác: whereIn, whereNotIn, whereNull, whereNotNull, whereDate, whereMonth, whereDay, whereYear, whereTime, whereColumn, whereExists, whereRaw.

Tài liệu của Laravel về Where Clauses.


Điều này sẽ được xử lý như thế nào nếu $from$tosẽ là ngày động thuộc về mô hình? Như trong có một effective_atexpires_atcác trường và tôi muốn truy vấn để xem liệu mục hiện tại có nằm trong phạm vi đó không. Tôi đã thử each()với nếu điều đó sử dụng Carbon::now()->between( ... ), tuy nhiên nó vẫn trả về tất cả các kết quả.
Rockin4Life33

4
CHỈNH SỬA cho nhận xét ở trên của tôi: Nhìn quá mức filter(), đó là mẹo. MyModel::all()->where('column', 'value')->filter(function ($item) { if (Carbon::now->between($item->effective_at, $item->expires_at)) { return $item; } })->first();
Rockin4Life33

1
@Anovative cảm ơn vì bình luận hữu ích của bạn. Tôi sẽ cập nhật câu trả lời của mình dựa trên nhận xét của bạn.
Peter Kota,

nó sẽ chỉ đưa ra từ bản ghi ngày.
Muhammad

1
Có một vấn đề với phương pháp thứ hai. Nó sẽ tải tất cả các bản ghi từ DB vào bộ nhớ và sau đó chỉ nó thực hiện việc lọc.
Jino Antony

12

Một tùy chọn khác nếu trường của bạn datetimethay vì date( mặc dù nó hoạt động cho cả hai trường hợp ):

$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
về mặt kỹ thuật, nó không cần phải là $ toDate. "23: 59.59.999"?
stevepowell2000,

@ stevepowell2000 Tùy thuộc vào cơ sở dữ liệu của bạn, trong trường hợp của tôi, chúng tôi lưu trữ ngày với định dạng này 'YYYY-MM-DD HH: MM: SS' trong trường mysql datetime, không có độ chính xác micro giây. Thông tin liên quan: dev.mysql.com/doc/refman/8.0/en/datetime.html
tomloprod

Điểm tuyệt vời. Vì vậy, nếu đó là trường ngày giờ hoặc trường dấu thời gian, chúng tôi có thể chuyển sang 23: 59: 59.999999 "Giá trị DATETIME hoặc TIMESTAMP có thể bao gồm một phần giây theo sau với độ chính xác lên đến micro giây (6 chữ số)."
stevepowell2000

1
cảm ơn bạn đã giúp tôi làm nhiệm vụ của tôi trước đây! yêu câu trả lời này người anh em! :) -habie
Habie Smart

10

Những điều sau sẽ hoạt động:

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

8

Nếu bạn muốn kiểm tra xem ngày hiện tại có tồn tại giữa hai ngày trong db hay không: => ở đây truy vấn sẽ nhận được danh sách ứng dụng nếu đơn của người sử dụng từ và đến nay tồn tại trong ngày.

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

7

Thử cái này:

Vì bạn đang tìm nạp dựa trên một giá trị cột, nên tương tự như vậy, bạn có thể đơn giản hóa truy vấn của mình:

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

Truy xuất dựa trên điều kiện: laravel docs

Hy vọng điều này sẽ giúp.


6

Và tôi đã tạo phạm vi mô hình

Thông tin thêm về phạm vi:

Mã:

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

Và trong bộ điều khiển, hãy thêm Thư viện Carbon vào đầu

use Carbon\Carbon;

HOẶC LÀ

use Illuminate\Support\Carbon;

Để có được kỷ lục 10 ngày qua kể từ bây giờ

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

Để có được kỷ lục 30 ngày qua kể từ bây giờ

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

1
WhereDateBet giữa param thứ hai cần phải là một mảng.
Mkey

Nó chỉ là một phạm vi của mô hình, nó không phải là phương pháp Builder
Manojkiran.

Oh yeah, đã bỏ lỡ điều đó bằng cách nào đó. My bad :)
Mkey

5

Nếu bạn cần phải có trường ngày giờ sẽ như thế này.

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

2
Xin chào, chào mừng bạn đến với Stack Overflow. Khi trả lời một câu hỏi đã có nhiều câu trả lời, hãy đảm bảo thêm một số thông tin chi tiết bổ sung về lý do tại sao câu trả lời bạn đang cung cấp là thực chất và không chỉ lặp lại những gì đã được người đăng gốc kiểm tra. Điều này đặc biệt quan trọng trong các câu trả lời "chỉ có mã", chẳng hạn như câu bạn đã cung cấp.
chb

3

Tôi biết đây có thể là một câu hỏi cũ nhưng tôi chỉ thấy mình ở trong tình huống phải triển khai tính năng này trong ứng dụng Laravel 5.7. Dưới đây là những gì đã làm việc từ tôi.

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

Bạn cũng sẽ cần sử dụng Carbon

use Carbon\Carbon;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.