mat*_*esj 1 mysql sql laravel eloquent laravel-5
即使有这样的多个问题,我也无法通过分组返回具有最近日期的行.
我有下表..
| 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
----------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我试着获取最近日期的行.
| message_id | from | to | created_at | status
----------------------------------------------
| 2 | 1 | 2 | 2017-04-07 | 0
| 4 | 3 | 4 | 2017-04-07 | 0
Run Code Online (Sandbox Code Playgroud)
目前,此查询返回具有上次最近日期的行.
$messages = Message::where('to', Auth::id())
->groupBy('from')
->orderBy('created_at', 'DESC')
->paginate(10);
Run Code Online (Sandbox Code Playgroud)
问题是结果集将首先分组然后排序.您可以使用嵌套选择来获得所需内容.
SQL查询:
SELECT t.* FROM (SELECT * FROM messages ORDER BY created_at DESC) t GROUP BY t.from
Run Code Online (Sandbox Code Playgroud)
与Laravel:
$messages = Message::select(DB::raw('t.*'))
->from(DB::raw('(SELECT * FROM messages ORDER BY created_at DESC) t'))
->groupBy('t.from')
->get();
Run Code Online (Sandbox Code Playgroud)
你只需要添加你的where()条款.
如果有人仍在寻找一个简短而雄辩的答案,groupBy()只需在后面latest()添加 即可...unique()get()
$unreadMessages = Message::where('receiver_id', Auth::user()->id)
->where('read_at', null)
->latest()
->get()
->unique('user_id');
Run Code Online (Sandbox Code Playgroud)
- - 更新 - -
上述解决方案的问题在于它unique()在结果集上使用方法,效率不高,因为它在从数据库检索结果集后对整个结果集进行操作。这可能很慢并且占用资源,特别是在处理大型数据集时。
解决方案1
$unreadMessages = Message::where('receiver_id', Auth::user()->id) ->where('read_at', null) ->latest('created_at') ->groupBy('user_id') ->得到();
在这里,我们使用groupBy()方法而不是unique()在结果集上使用。应用groupBy()在数据库级别,效率会高很多。
解决方案2
$unreadMessages = Message::select('user_id', DB::raw('max(created_at) as max_created_at'), DB::raw('*')) ->where('receiver_id', Auth::user( )->id) ->where('read_at', null) ->groupBy('user_id') ->get();
在此查询中,我们选择user_id、 、max(created_at) as max_created_at和 ,*这将给出所有列。
通过使用groupBy('user_id')只会选择不同的 user_id,并且使用max(created_at) as max_created_at它将为您提供每个用户的最新消息。这样,您可以通过对数据库的单个查询来检索每个用户的最新未读消息。
要获取每个记录的最新记录,from您可以使用自连接
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);
Run Code Online (Sandbox Code Playgroud)
在 SQL 中它看起来像
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
Run Code Online (Sandbox Code Playgroud)
Laravel Eloquent 选择具有 maxcreated_at 的所有行
| 归档时间: |
|
| 查看次数: |
4969 次 |
| 最近记录: |