正如@JonasStaudenmeir在laravel eager loading with limit上回答的那样,查询看起来像:
User::select('id')
->with([
'posts' => fn($query) => $query->select(['id', 'user_id'])->limit(4)
])
->limit(2)
->get();
字符串
x1c 0d1x的数据
select `id` from `users` limit 2
select * from (select `id`, `user_id`, row_number() over (partition by `posts`.`user_id`) as laravel_row from `posts` where `posts`.`user_id` in (1, 3)) as laravel_table where laravel_row <= 4 order by laravel_row
型
现在,我的兴趣是手动操作,这是我在这里尝试的:
User::select('id')
->with([
'posts' => fn($query) => $query->select(['id', 'user_id'])
->selectRaw("row_number() over (partition by `posts`.`user_id`) as laravel_row")
->where('laravel_row', '<=', 4)
->orderBy('laravel_row')
])
->limit(2)
->get();
型
另外,我从在线(SQLtoEloquent)获得了一些帮助,但是语法没有正确形成,所以它也失败了。
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'laravel_row' in 'where clause'
select `id`, `user_id`, row_number() over (partition by `posts`.`user_id`) as laravel_row from `posts` where `posts`.`user_id` in (1, 3) and `laravel_row` <= 4 order by `laravel_row` asc
型
更新:
按照@Igor的建议,我试图使它与包相似,更方便,但与预期的输出不匹配。
- App\Providers\AppServiceProvider.php*
public function boot(): void
{
\Illuminate\Database\Eloquent\Relations\Relation::macro('limit', function(int $value) {
if($this->parent->exists) {
$this->query->limit($value);
} elseif ($value >= 0) {
// When I tried on the Model(User), it succeeded the below logic
// 2 was expected because the total number of users fetched is 2 but it didn't happen
$parentLimitValue = $this->query->getQuery()->limit; // null
// $parentLimitValue = $this->parent->getQuery()->limit; // null
// $parentLimitValue = $this->related->getQuery()->limit; // null
$parentLimitValue ??= 1;
$this->query
->selectRaw("row_number() over (partition by ".$this->getExistenceCompareKey().") as laravel_row")
->orderBy('laravel_row')
->limit($value * ($parentLimitValue ?: 1));
}
return $this;
});
}
型
有人知道我应该把我的眼睛最小化这个包吗?
2条答案
按热度按时间9rygscc11#
我认为您需要删除where,并在子查询中添加limit
字符串
更新
要限制每个用户的用户数和帖子数,请使用以下操作:
型
mu0hgdu02#
根据@Igor的回复,我把它放在traits和本地作用域中,使它更方便。
字符串
在相应模型上使用
WithEagerLimit
trait。型
现在,您可以通过执行以下操作将
withEagerLimit()
链接到任何查询:简单的紧急加载功能
型
即时加载功能的条件
型
快速加载功能的复杂SQL RAW查询
型
即时加载分页功能
型
对于那些急切等待答案的人
您应该调用
->limit($value)
或等效的方法(即take()
、skip()
、paginate()
或类似过程)在主查询和子查询中与->withEagerLimit($relationName, $callback)
链接的任何查询中。型
只有当查询在两个表上都满足足够的结果时,才能得到使用此trait的好处。users & posts。否则,您将获得额外的结果,因为这里我们已经完成了
UsersLimit x PostsLimit
,因此相应地保留查询。