讨论数量:
我前段时间也咨询过这个问题
问答:请问如何查询每个分类下的前 N 条记录?
后来我是这样解决的
ArticleCategory::whereIn('id', [1, 2, 3])->with(['articles' => function ($query) {
$table = $query->getRelated()->getTable(); //获取当前依赖表名称
$query->whereRaw('( SELECT COUNT(*) FROM `' . $table . '` AS `temp` WHERE `' . $table . '`.`category_id` = `temp`.`category_id` AND `' . $table . '`.`id` > `temp`.`id`) <= 10'); //10获取10条记录 (table.id > temp.id) >号ID从小到大,<号获取最新的
}])->get();
首先你没有搞清楚预加载的原理,预加载首先会一次性查询出符合外键查询需求的所有数据,然后脱离mysql后进行配对的。你限制了总共查询3条数据等于总共查询出了3条,所以只能配对这3条数据。
所以你的思路应该变更为如何让第一次一次性查询到的数据刚好服你的每条只要前3条的需求,筛选出这些ID,然后再用回调的query去获取对应的值就好;
这里关系表只是举例,你更换表名即可;
$list = Category::query()->whereIn('id', [1,2])
->with(['topics' => function($q) {
$topics = Topic::query()->whereIn('category_id',[1,2])
->select('id','category_id')
->get()
->groupBy('category_id');
$col = collect();
foreach ($topics as $topic) {
$res = $topic->filter(function ($value, $key) {
return $key < 3;
});
$col = $col->merge($res);
}
$ids = $col->pluck('id')->toArray();
$q->find($ids);
}])
->get();
@waney 这就要看你业务的具体需求了,这个方法也仅仅是迎合题意。如果你是真实业务需求,redis弄个list或set都可以,速度绝对流畅。如果一定要用mysql的话,把第一步whereIn换成循环limit 3吧。如果分类少的话还是很流畅的。
public function threePosts()
{
return $this->hasMany('App\Models\Post')->take(3);
}
$categories = Category::whereIn('id', [3, 4, 5, 6])->get();
$categories->each(function ($category) {
$category->load('threePosts');
});
然后你再循环输出category
和threePost
试试.
推荐文章: