搞定,这个$count才是group by 真正需要的分页总条数,写法也够优雅。得到了$count不管你采用的那种分页方式,改有的数据都有了,按照分页规则把值填上,分页完成。
最近做数据统计,有很多group by查询,发现分页处理是一个棘手的问题。今天就来探讨一下group by 分页处理的问题。
我们先看一下分页处理都需要那些数据。
$pageNumber = input('param.pageNumber');//客户端传过来的分页
$limit = isset(input('param.pageSize')) ?:20//每页显示条数
$offset = $pageNumber * $limit;//查询偏移值
$data = Db::name('users')->limit($offset, $limit)->select();//查询数据
$count = Db::name('users')->count();//查询的总条数
return ['list'=>$list, 'count'=>$count];
以上就是简化的分页查询的例子,客户端需要传递$pageNumber和$pageSize,返回给客户端除了了数据外,必须要有$count查询的总条数。服务器端的查询分页处理必须这些参数和数据。
为什么group by分页是个问题呢,其根源在于$count总条数的获取问题。以上获取$count的方式不再适用。假如,现在users表中的有一个timestamp类型的字段time记录注册用户的时间,我们要获取每天注册用户数量的列表,按照传统的做法你可能会想到这么做:
$count = Db::name('users')->group("date('time')")->count();
//转化为sql元素为:
$count = Db::query("select count(*) from users group by date('time') ");
以上的获取方式显然是不对,count(*)统计的是每一个分组的所包含的条数,而不是整个group by查询处理的行数。
说了那么多的不行,那么我们来看看正确的group by分页的查询姿态。
$count = Db::query("select count(*) from (select date('time') as date
from users group by date) as u ");
ok,安装正常的解决逻辑,以上答案应该是每一个人都能够想的。但是子查询总是让人看着不舒服,sql写的不过优雅。对于sql能不用子查询就尽量不要用子查询。
mysql总是强大的,提供了一种更优雅的写法。
//SQL_CALC_FOUND_ROWS记录查询条数
//在测试中发现,mysql5.7中添加关键词SQL_CALC_FOUND_ROWS不是必须的。
Db::query("select SQL_CALC_FOUND_ROWS date('time') as date from users group by date");
//found_rows()获取以上查询记录的条数
$count = Db::query("select found_rows() as count");
搞定,这个$count才是group by 真正需要的分页总条数,写法也够优雅。得到了$count不管你采用的那种分页方式,该有的数据都有了,按照分页规则把值填上,分页完成。
以上是基于thinkphp确切的说是thinkphp5下group by分页处理的解决方式。你可能会发现在这个问题上tp框架发挥的作用好像不大,只应用了Db::query()数据库链接查询的接口,tp5有没有封装相应的函数来解决此类问题,这个问题你要找tp5作者了,反正手册是没找到。不过我觉得完全没有必要,一些比较复杂的查询使用原生sql是最灵活方便的。 记得刚才是学习php时候,有一个老师对我们说,我们使用框架,但不要被框架所限制。其中的道理,大家自己体会吧。
除特别注明外,本站所有文章均为作者原创。 或分享自己的编程经验,或探讨工作中的问题,或聊以人生趣事。 转载请注明出处来自 https://www.qiusuoweb.com/71.html
运营天数
总访问量
文章数量
-
-
-
交流群:157451741
新浪微博:草莽兴
发布评论