Get most recent row with group by and Laravel

2019-01-29 04:15发布

问题:

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..

| message_id | from | to | created_at | status
----------------------------------------------
|    1       |   1  |  2 | 2017-04-06 |   1
|    2       |   1  |  2 | 2017-04-07 |   0
|    3       |   3  |  4 | 2017-04-06 |   1
|    4       |   3  |  4 | 2017-04-07 |   0
----------------------------------------------

and I'm tryin to get the rows with most recent date.

| message_id | from | to | created_at | status
----------------------------------------------
|    2       |   1  |  2 | 2017-04-07 |   0
|    4       |   3  |  4 | 2017-04-07 |   0

Currently this query returns the rows with the last recent date.

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

回答1:

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.



回答2:

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.



回答3:

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