如何在MYSQL中的单个查询中计算和限制记录?

时间:2009-04-29 13:31:34

标签: php mysql count

我在表格中搜索记录如下:

SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

现在,我正在添加LIMIT来维护我的分页。但是当用户搜索单词'prashant'时,我的总记录为'prashant'为124。但是,由于限制应用于查询,因此它只在我的PHP脚本中获取10条记录,当我在PHP代码中计算mysql变量时,它返回的总记录数为10。

所以基本上我想使用单个查询来计算和限制,通过在上面的查询中进行一些修改,我想要记录的总数(124)。我不想运行单独的count(*)查询来计算查询找到的总结果。

感谢。

5 个答案:

答案 0 :(得分:17)

SELECT SQL_CALC_FOUND_ROWS
  Id, Name
FROM my_table
WHERE
  Name LIKE '%prashant%'
LIMIT 0, 10;

# Find total rows
SELECT FOUND_ROWS();

more info

答案 1 :(得分:9)

MySQL支持使用Ionut提到的SQL_CALC_FOUND_ROWS来执行此操作。然而,事实证明in many cases使用两个语句以老式方式执行它实际上更快,其中一个是常规count()。然而,这确实需要使用索引扫描来完成计数,这不是这个查询的情况,但我认为无论如何我都会提到它。

答案 2 :(得分:6)

这是针对具有相同需求的其他人(考虑到这个问题已经过了3年)。

我有类似的问题,我不想创建2个查询。所以我做的是为总数创建一个额外的列,并在最后移动LIMITOFFSET子句:

SELECT SQL_CALC_FOUND_ROWS * FROM (
    SELECT `id`, `name`
    FROM `my_table`
    WHERE `name` LIKE '%prashant%'
) res,
(SELECT /*CEIL(FOUND_ROWS()/10) AS 'pages',*/ FOUND_ROWS() AS 'total') tot
LIMIT 0, 10

所以结果就像

| id  |      name      | total |
+-----+----------------+-------+
|  1  | Jason Prashant |  124  |
|  2  | Bob Prashant   |  124  |
|  3  | Sam Prashant   |  124  |
|  4  | etc. prashant  |  124  |

我认为这个解决方案在计时方面没有任何缺点,因为它只获取一次结果,然后使用已经计算的行计数用于附加列。

答案 3 :(得分:2)

如果是巨大的表并选择多个字段(不仅仅是Id,您的示例中的名称),我建议使用2个查询。首先用所有WHERE子句选择count(0)然后再构建分页,选择数据等。 例如,它会在一些流行的电子商务网站上运行得更快。

答案 4 :(得分:0)

不要使用SQL_CALC_FOUND_ROWS和FOUND_ROWS()

  1. 有报道的错误 在这里:https://bugs.mysql.com/bug.php?id=18454
    在这里:https://bugs.mysql.com/bug.php?id=19553

  2. 在小表上,BENCHMARK更多地依赖于其他东西,SELECT所需的时间与COUNT(0)大致相同 - SQL_CALC_FOUND_ROWS仍然限制LIMIT和ORDER BY数据库优化,所以如果你依赖于他们不使用 SQL_CALC_FOUND_ROWS

  3. 在大型表格中,BENCHMARK差异变得很大,其中COUNT(0)可能需要0.003秒,相同的SQL_CALC_FOUND_ROWS可能需要20秒

  4. 通过所有方法,COUNT(0)是最佳选择

    COUNT(0)语法:

    (SELECT COUNT(0) FROM tableNames WHERE condition) AS alias
    // alias is optional but needed if you need to use the result later
    

    所以你的总查询看起来像这样

    (SELECT COUNT(0) FROM my_table WHERE name LIKE '%prashant%') AS countResults;
    
    SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
    

    然后只需在其他地方调用countResults即可......

    使用COUNT(0)的另一个好处是你可以用它来搜索同一个表,也可以用它来搜索不同的表......

    因此,例如,如果每个人发现也分别有3个,2个,1个,5个不同的工作......你可以添加一个

    (SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs
    

    在你原来的SELECT里面

    SELECT Id, Name (SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
    

    给你:

    --------------------
    | id | Name | jobs |
    --------------------
    | 1  | Alice| 3    |
    --------------------
    | 2  | John | 2    |
    --------------------
    | 3  | Bob  | 1    |
    --------------------
    | 4  | Jill | 5    |
    --------------------
    

    因此,当显示名称[3](即Bob)时,您还可以通过调用作业[3]来显示Bob有1个工作...

相关问题