Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Yuray's avatar

How to get last entry for model in given date range from pivot table

Ok, i'm stuck and really need help pls.

this is setup:

  1. table items: id, name

  2. table statuses: id, title

  3. table item_status: id, item_id, status_id, created_at

item model has relation:

public function statuses(){
    return $this->belongsToMany('Status')->withTimestamps();
}

now, i want items with LATEST statuses '7' or '9', created between 2015-10-19 and 2015-10-20 closest i got is:

$items = Item::with('statuses')->whereHas('statuses', function ($q) {
                                        $q->where('created_at','>=','2015-10-19');
                                        $q->where('created_at','<','2015-10-20');
                                        $q->whereIn('status_id',array('7','9'));
                                    }
                    );

Problem is that this is not working right. It gives all items that got one of these status_id's in that date range. So if item got status '7' on 2015-10-19, and for example status '11' on 2015-10-22, it will be in result. I would like to have only items with latest (newest) status '7' or '9' in that date range.

please help! tnx Y

0 likes
11 replies
bobbybouwmann's avatar

Grab only the last created item based on the conditions

$projects = Item::with('statuses')
    ->whereBetween('created_at', array(Carbon::now(), Carbon::now()->addWeek()))
    ->whereIn('status_id', [7, 9])
        ->orderBy('created_at', 'desc')
    ->first();

Grab a list of items based on the conditions ordered by latest added

$projects = Item::with('statuses')
    ->whereBetween('created_at', array(Carbon::now(), Carbon::now()->addWeek()))
    ->whereIn('status_id', [7, 9])
        ->orderBy('created_at', 'desc')
    ->get();
stefanbauer's avatar

the "created_at" .. :-) I think he mixed his mother tongue with english :-D

Yuray's avatar

i see... but something doesn't seems ok... i don't want items which are created between dates, but pull only item ids from pivot table which have last (most recent) status in given period. for ex.

item_status
item_id status_id   created_at
1       1       2015-10-06
1       3       2015-10-07
2       6       2015-10-07
2       3       2015-10-08
2       5       2015-10-09

if i set filter as: status_id = 3 and date range 2015-10-07 to 2015-10-09: i want only ITEM 1, because ITEM 2 in given period has another, newer status (5)

it's kinda hard to explain... but hope you get it. tnx

Yuray's avatar

no, i get "Column not found: 1054 Unknown column 'status_id' in 'where clause' ... i don't have 'status_id' column in items table...

bobbybouwmann's avatar

You can make your own query right? I don't know your database structure... I just copied your example and I see know that you have a whereHas so in that case you need something like this

$projects = Item::with('statuses')->whereHas('statuses', function ($query) {
    $query->whereBetween('created_at', array(Carbon::now(), Carbon::now()->addWeek()))
    $query->whereIn('status_id', [7, 9])
})->orderBy('created_at', 'desc')->first();

Please for the next time! Think for yourself. You could easily just remove the column and continue right?

Yuray's avatar

if i could make it on my own, i wouldn't ask here. i stated table strucures at begining of question. Thanks for your effort, but i don't think you understand problem here. Your code is pretty much same as mine from 1st post. look at example table i put 4 posts before... if you use

$items = Item::with('statuses')->whereHas('statuses', function ($q) {
                                        $q->where('created_at','>=','2015-10-06');
                                        $q->where('created_at','<','2015-10-09');
                                        $q->whereIn('status_id',array('3'));
                                    }
                    );

i will get ITEM 1 and ITEM 2, but i need only ITEM 1 because in given period ITEM 2 has another, newer status (5)

i tried to add another relation method to item model:

public function lateststatus(){
    return $this->belongsToMany('Repairstatus')
        ->orderBy('item_status.created_at','desc')
        ->withTimestamps()
        ->limit(1,0);
}

and then tried to use that method, but result was same

$items = Item::with('lateststatus')->whereHas('lateststatus', function ($q) {
                                        $q->where('created_at','>=','2015-10-06');
                                        $q->where('created_at','<','2015-10-09');
                                        $q->whereIn('status_id',array('3'));
                                    }
                    );
Yuray's avatar

Here's SQL that did thing. Is there way to make it through Eloquent? INNER JOIN part is for "ordering" before GROUP BY, - i needed results grouped by item_id, but most recent entries.

SELECT t1.item_id FROM item_status t1
    INNER JOIN (
                    SELECT MAX(created_at) created_at, item_id
                    FROM item_status 
                GROUP BY item_id
                     ) t2
    ON t1.item_id = t2.item_id 
    AND t1.created_at = t2.created_at 

WHERE t1.status_id in (3), 
    AND t1.created_at >= '2015-10-06' 
    AND t1.created_at < '2015-10-09'

Please or to participate in this conversation.