自定义 Laravel 分页计数查询

Abi*_*tro 5 mysql pagination laravel

我有一个 Laravel 分页查询 -

$query = static::newQuery();
$query->join('users AS u', 'comments.created_by', '=', 'u.id');
$query->leftJoin('users AS u1', 'comments.updated_by', '=', 'u1.id');
$query->leftJoin('images AS i', 'i.id', '=', 'u.image_id');
$query->selectRaw('comments.id, text, html, comments.created_by, comments.updated_by, comments.created_at, comments.updated_at, '
        . 'u.name AS created_by_name, u1.name AS updated_by_name, '
        . '(SELECT count(c.id) FROM bookstack.comments c WHERE c.parent_id = comments.id AND page_id = ?) AS cnt_sub_comments, i.url AS avatar ', 
        [$pageId]);

if (empty($commentId)) {
    $query->whereRaw('page_id = ? AND parent_id IS NULL', [$pageId]);
} else {
    $query->whereRaw('page_id = ? AND parent_id = ?', [$pageId, $commentId]);
}        
$query->orderBy('created_at');
return $query;
Run Code Online (Sandbox Code Playgroud)

然后我对查询对象运行分页。

$query->paginate($count); 
Run Code Online (Sandbox Code Playgroud)

这会导致运行以下查询 -

select comments.id, text, html, comments.created_by, comments.updated_by, comments.created_at, comments.updated_at, u.name AS created_by_name, 
u1.name AS updated_by_name, (SELECT count(c.id) FROM bookstack.comments c WHERE c.parent_id = comments.id AND page_id = '2') AS cnt_sub_comments, 
i.url AS avatar  from `comments` inner join `users` as `u` on `comments`.`created_by` = `u`.`id` 
left join `users` as `u1` on `comments`.`updated_by` = `u1`.`id` 
left join `images` as `i` on `i`.`id` = `u`.`image_id` 
where page_id = '2' AND parent_id = '2' order by `created_at` asc limit 20 offset 0
Run Code Online (Sandbox Code Playgroud)

此外还运行以下计数查询,

select count(*) as aggregate from `comments` inner join `users` as `u` on `comments`.`created_by` = `u`.`id` 
left join `users` as `u1` on `comments`.`updated_by` = `u1`.`id` 
left join `images` as `i` on `i`.`id` = `u`.`image_id` 
where page_id = '2' AND parent_id = '2'
Run Code Online (Sandbox Code Playgroud)

是否可以让计数查询不在这里进行不必要的 JOIN ?

小智 0

您需要了解分页的工作原理。由于您的查询需要连接到其他表,并添加了复杂的选择(例如:在选择参数上包含类似月份的函数)。查询本身必须与子查询连接(如上所述)。

这个问题的正确答案是将上面的查询转换为视图表。并将视图视为模型上的表。当你跑步时,你将输入比现在更少的代码。通过这种视图,您将在开发过程中减少错误/警告。

正如我之前提到的使用视图,您不能仅将其设置为 1 个视图。根据该查询创建视图

SELECT count(c.id) FROM bookstack.comments c WHERE c.parent_id = comments.id AND page_id = '2'
Run Code Online (Sandbox Code Playgroud)

然后在 user_comment (视图)上使用它。这不是一个简单的答案,但这种方法可以使您的代码可读。