Ser*_*gio 7 php laravel eloquent
我有一个包含以下列的"消息"表
CREATE TABLE `messages` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fromId` int(11) NOT NULL,
`toId` int(11) NOT NULL,
`message` text NOT NULL,
`status` int(11) NOT NULL,
`device` varchar(100) NOT NULL,
`createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)
我正在尝试获取所有消息,其中'toId'= $ id并按fromId进行分组.问题是结果上显示的"消息"是第一个,而不是最新的.我尝试通过createdAt订购,但它不起作用.
在查询和分组结果之前,如何通过"createdAt"订购?我想用Eloquent以laravel方式做到这一点.
我的查询:
$chats = Message::with('sender','recipient')
->where('toId',$id)
->orderBy('createdAt')
->groupBy('fromId')
->paginate(10)
Run Code Online (Sandbox Code Playgroud)
小智 29
我只需要用消息模型做类似的事情.对我有用的是将该unique方法应用于返回的雄辩集合.
Model::where('toId', $id)
->orderBy('createdAt', 'desc')
->get()
->unique('fromId');
Run Code Online (Sandbox Code Playgroud)
该查询将返回所有订购的消息,createdAt并且该unique方法会将其减少为每个消息fromId.这显然不如直接使用数据库那样高效,但在我的情况下,我对查询有进一步的限制.
此外,还有许多有用的方法可以使用这些集合:https://laravel.com/docs/5.2/collections#available-methods
我找到了办法!基本上,创建一个子查询并在之前运行它,以便结果按预期排序并在之后分组.
这是代码:
$sub = Message::orderBy('createdAt','DESC');
$chats = DB::table(DB::raw("({$sub->toSql()}) as sub"))
->where('toId',$id)
->groupBy('fromId')
->get();
Run Code Online (Sandbox Code Playgroud)
应该是这样的:
Message::whereToId($id)->groupBy('fromId')->latest('createdAt')->first();
Run Code Online (Sandbox Code Playgroud)
更新
查看您添加的查询后,您可能只需要向该orderBy函数添加一个方向,如下所示:
$chats = Message::with('sender','recipient')
->select(DB::raw('*, max(createdAt) as createdAt'))
->where('toId',$id)
->orderBy('createdAt', 'desc')
->groupBy('fromId')
->paginate(10)
Run Code Online (Sandbox Code Playgroud)
试试这个查询:
$chats = Message::with('sender','recipient')
->where('toId',$id)
->whereRaw('id IN (select MAX(id) FROM messages GROUP BY fromId)')
->orderBy('createdAt','desc')
->paginate(10)
Run Code Online (Sandbox Code Playgroud)