mysql 分组查询数据时,如何获得用于分页的总记录数?

来源:互联网 发布:.date域名过期 编辑:程序博客网 时间:2024/04/27 17:06

主要是想查询符合条件的记录总数,

查询数据使用的sql为:

  1. SELECT SUBSTRING_INDEX(`url`,'/',3) AS host,COUNT(*) AS count FROM `tab` WHERE `type`=4 GROUP BY host HAVING(count >= 5) ORDER BY count desc LIMIT 0,10

以下是一些尝试过的方法:

方法一: 一般情况下可以使用DISTINCT来查询总数

  1. select count(DISTINCT SUBSTRING_INDEX(`url`,'/',3)) as c from tab where type = 4

但是 查询数据中的sql 有 having 子句,这样得到的总数是没有经过条件筛选的。这个结果是错误的。

方法二: 通过 SQL_CALC_FOUND_ROWS 选项忽略 LIMIT 子句,然后通过FOUND_ROWS()获得查询总数,那么sql改为:

  1. SELECT SQL_CALC_FOUND_ROWS SUBSTRING_INDEX(`url`,'/',3) AS host,COUNT(*) AS count FROM `tab` WHERE `type`=4 GROUP BY host HAVING(count >= 5) ORDER BY count desc LIMIT 0,10

再通过 select FOUND_ROWS(); 获得总数

这样获得的总数没问题,但是由于分页程序需要先获得符合条件的总数,才能生成 page_list ,以及验证offset,和总页数等信息,所以不能先查询数据再得总数。

方法三:和上边的方法类似,只是第一次使用sql获得总数

先:

  1. SELECT SUBSTRING_INDEX(`url`,'/',3) AS host,COUNT(*) AS count FROM `tab` WHERE `type`=4 GROUP BY host HAVING(count >= 5)

然后:

  1. select FOUND_ROWS();

最后:

  1. SELECT SUBSTRING_INDEX(`url`,'/',3) AS host,COUNT(*) AS count FROM `tab` WHERE `type`=4 GROUP BY host HAVING(count >= 5) ORDER BY count desc LIMIT 0,10

这个没有问题,也可以避免方法二中的问题,但是会返回全部的符合条件的数据,并且返回的数据没有任何作用,只是查询一次总数,所以也不可取。

方法四:使用子查询

  1. select count(*) as count from (select SUBSTRING_INDEX(url,'/',3) as host,count(*) as c from tab where type=4 group by host having(c >= 5)) as temp

这个基本满足了需要,但是效率不是很高,如果子集很大的话,性能上是个问题。

不知道大家还有什么更好的方法? 或者我上述方法中还可以怎么优化?

0 0