Get most recent row with group by and Laravel

前端 未结 5 1756
悲哀的现实
悲哀的现实 2020-12-18 14:34

Even though there are multiple questions like this I can\'t get my query to return the row with the most recent date with a group by.

I have the following table..

相关标签:
5条回答
  • 2020-12-18 15:08

    To get most recent record for each from you can use a self join

    DB::table('message as m')
      ->select('m.*')
      ->leftJoin('message as m1', function ($join) {
            $join->on('m.from', '=', 'm1.from')
                 ->whereRaw(DB::raw('m.created_at < m1.created_at'));
       })
      ->whereNull('m1.from')
      ->orderBy('m.created_at', 'DESC')
      ->paginate(10);
    

    In SQL it will look like

    select m.*
    from message m
    left join message m1 on m.from = m1.from
    and m.created_at < m1.created_at
    where m1.from is null
    order by m.created_at desc
    

    Laravel Eloquent select all rows with max created_at

    0 讨论(0)
  • 2020-12-18 15:13

    The problem is that the result set will be first grouped then ordered. You can use nested select to get what you want.

    SQL Query:

    SELECT t.* FROM (SELECT * FROM messages ORDER BY created_at DESC) t GROUP BY t.from
    

    With Laravel:

    $messages = Message::select(DB::raw('t.*'))
                ->from(DB::raw('(SELECT * FROM messages ORDER BY created_at DESC) t'))
                ->groupBy('t.from')
                ->get();
    

    You just need to add your where() clauses.

    0 讨论(0)
  • 2020-12-18 15:19

    You might also want to orderBy message_id as well

    $messages = Message::where('to', Auth::id())
                        ->groupBy('from')
                        ->orderBy('created_at', 'DESC')
                        ->orderBy('message_id', 'DESC')
                        ->paginate(10);
    
    0 讨论(0)
  • 2020-12-18 15:24

    You've got a date field in your example, not a datetime field, so the following is my preferred method:

    # Mysql
    select * from
      your_table
    where date_field = (select max(date_field) from your_table)
    
    // Laravel
    YourModel:::query()->whereRaw('date_field = (select max(date_field) from your_table)')->get();
    
    • Note the above wont work as expected for datetime fields because the rows will have different timestamps, it'll likely just return the single latest row.
    0 讨论(0)
  • 2020-12-18 15:29

    You may replace groupBy with distinct, as it works in my case.

    $messages = Message::where('to', Auth::id())
                    ->orderBy('created_at', 'DESC')
                    ->distinct('from')
                    ->paginate(10);
    

    Hope this helps.

    0 讨论(0)
提交回复
热议问题