0

I have a table structured as following named renewals.

------------------------------------------------
| id  | membership_id| valid_from | valid_upto |
------------------------------------------------
|  1  | 1            | 2015-02-15 | 2016-02-15 |
|  2  | 2            | 2015-05-16 | 2016-05-16 |
|  3  | 2            | 2016-05-16 | 2017-05-16 |
|  4  | 3            | 2014-06-16 | 2015-06-16 |
|  5  | 3            | 2015-06-16 | 2016-06-16 |
|  6  | 3            | 2016-06-16 | 2017-06-16 |
|  7  | 1            | 2016-02-15 | 2017-02-15 |
------------------------------------------------

I need to get record of each members with latest valid_upto date. How to do that using Laravel Eloquent. Any other easy method will be appreciated.

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
Bibash Adhikari
  • 292
  • 4
  • 16

6 Answers6

0

In User Model

public function latest_renewal()
{
    return $this->hasOne('App\Renewals', 'membership_id')->latest('valid_upto');
}

In controller

$users = User::with('latest_renewal')->get();
/*
 [
   {
     'id' => 1,
     'name' => 'user1',
     'latest_renewal' => {
         'id' => 7,
         'membership_id' => 1,
         'valid_from' => '2016-02-15',
         'valid_upto' => '2017-02-15',

     }
   },
   {
     'id' => 2,
     'name' => 'user2',
     'latest_renewal' => {
         'id' => 3,
         'membership_id' => 2,
         'valid_from' => '2016-05-16',
         'valid_upto' => '2017-05-16',

      }
    }
 ]
Praveen Tamil
  • 1,076
  • 11
  • 22
0
Renewals::groupBy('membership_id')->havingRaw('MAX(valid_upto)')->get();

or

Renewals::groupBy('membership_id')->having( function( $query )
{
    $query->latest('valid_upto');
})->get();
0

In plain MySQL, you could get your latest records per member by following:

select a.*
from renewals a
left join renewals b on a.membership_id = b.membership_id
and a.valid_upto < b.valid_upto
where b.membership_id is null

DEMO

Using Laravel, you could write it using query builder as:

DB::table('renewals as a')
  ->select('a.*')
  ->leftJoin('renewals as b', function ($join) {
        $join->on('a.membership_id','=','b.membership_id')
             ->whereRaw(DB::raw('a.valid_upto < b.valid_upto'));
   })
  ->whereNull('b.membership_id')
  ->get()
halfer
  • 19,824
  • 17
  • 99
  • 186
M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118
0

May be something simlilar to this

DB::statement("SET SQL_MODE=''");

Renewal::groupBy('membership_id')
         ->latest('valid_upto')
         ->get();

Read more about the first SET SQL_MODE: Laravel : Syntax error or access violation: 1055 Error

hungtran273
  • 1,180
  • 9
  • 11
0
$data = Renewal::get();
$groups = $data->groupBy('membership_id');
$results = [];
foreach($groups as $group) {
   /*collection*/
   $results[] = $group[0];
}
return $results;

source : https://stackoverflow.com/a/29731825/13381751

Nitsh
  • 79
  • 3
-1

You can use below query for your purpose.

$renewals = Renewals::groupBy('membership_id')->orderBy('valid_upto','desc')->get();
halfer
  • 19,824
  • 17
  • 99
  • 186
AddWeb Solution Pvt Ltd
  • 21,025
  • 5
  • 26
  • 57