选择行数作为额外列的MySql?

时间:2012-03-29 05:40:02

标签: php mysql sql

我需要一个MySql语句来选择所有行,以及总行数。

我正在使用

mysql_query("SELECT * FROM posts LIMIT 0, 5");

...尝试添加计数:

mysql_query("SELECT *, COUNT(*) AS total FROM posts LIMIT 0, 5");

...但只返回一行。

此外,如果有更好的方法来获得总数而不是为每一行添加额外的列,那么我希望这样做。谢谢!

3 个答案:

答案 0 :(得分:9)

  

我需要一个MySql语句来选择所有行,以及总行数。

从字面上看,这是不可能的。 SQL查询的结果是(虚拟)表;该结果表中每行中的列提供仅与该行关联的值,并且这些行实际上彼此独立。

有很多方法可以获取整个结果的行数,但它可以在两个语句中完成,也可以在概念上与您拥有的查询不同。 (以下解决方案)

原始问题中有一个方面可以用多种方式解释:

  

以及总行数

这可能意味着:

  1. 计算结果中返回的每一行。
  2. 如果LIMIT子句不是(在这种情况下将结果截断为5行),则计算将返回的每一行
  3. (我将在下面提出答案)

      

    但只返回一行。我猜它是因为COUNT(*)对于每一行都是相同的,并且由于某种原因,MySql只返回具有唯一值的行吗?我不知道。

    COUNT是一个聚合函数。通过使用聚合函数,您可以要求数据库将行组合在一起并将其某些方面投影到一行中。令人困惑的是,mysql也可以将非聚合和聚合表达式混合在同一个SELECT列表中。大多数其他数据库不允许这样做,并为此提供错误,但唉,MySQL没有。

    但COUNT(*)仍将所有行聚合为一行,代表整行行。

      

    此外,如果有更好的方法来获得总数而不是为每一行添加额外的列,那么我希望这样做。谢谢!

    是的,有几种方法。

    如果你想获得返回给PHP的行数,那么,在MySQL应用了它的limit子句之后,我建议在执行{{1}之后简单地调用php函数mysql_num_rowshttp://www.php.net/manual/en/function.mysql-num-rows.php)调用。

    如果你想获得在没有mysql_query子句的情况下返回的行数,我建议分2步执行:首先,执行原始查询的略微修改版本,然后之后,立即调用MySQL的LIMIT函数。 (见http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_found-rows

    看起来像这样:

    FOUND_ROWS

    $result = mysql_query('SELECT SQL_CALC_FOUND_ROWS * FROM posts LIMIT 0, 5'); //do stuff with the result, but don't do any other queries //get the total number of rows (disregarding the LIMIT clause) $result = mysql_query('SELECT FOUND_ROWS()'); 修饰符告诉MySQL在应用SQL_CALC_FOUND_ROWS子句之前跟踪总行数,LIMIT返回该数字。牢记两件事:

    1. 这两个FOUND_ROWS()调用都应该在同一个连接上执行
    2. 不要在这些mysql_query
    3. 的来电之间执行其他查询

      哦,最后注意事项:使用mysql_query时,您通常希望以特定方式对结果进行排序。通常人们使用LIMIT进行分页。如果您不对行进行排序,则顺序是不确定的,后续查询可能会返回先前语句已返回的行,即使LIMIT偏移量不同也是如此。您可以使用LIMIT子句显式地对结果进行排序。 (http://dev.mysql.com/doc/refman/5.5/en/select.html

答案 1 :(得分:8)

我不确定您在想什么总数:当前选择的总数或整个表中所有行的数量。这将返回整个表中所有行的数量,当然每行中的值相同:

mysql_query("SELECT *, (select COUNT(*) from posts) AS total FROM posts LIMIT 0, 5");

答案 2 :(得分:1)

我认为你这个问题过于复杂。我没有看到使用两个查询的问题。

获取总帖子的第一个查询(我假设你想要整个表格中的总数):

SELECT COUNT(*) AS total FROM posts;

还有一秒,查询你的帖子:

SELECT * FROM posts LIMIT 0, 5

原因是使用多个查询检索数据并不总是坏事,特别是当它有意义时。

如果你使用一个子查询添加它作为一个额外的列,你会在每一行中得到总数,但你仍然基本上会运行两个查询(或者每个行运行子查询,我可以记得吗?)

它还提供了更多的灵活性来获取计数,因为一些查询将返回错误的总计数,具体取决于查询的复杂程度。并且您可能需要修改计数查询,以便获得正确的总数并且可以正确分页。

例如,在一对多查询的情况下,假设您想要获得帖子和评论,您会得到错误的计数,因为该帖子的每个评论都会重复发布。

缩写示例:

post_id | comment_id
1       | 1
1       | 2
2       | 3
3       | 4
3       | 5

所以为了正确地做到这一点,你首先需要运行以下查询来获得总帖子:

SELECT COUNT(*) AS total FROM posts;

然后你需要运行:

SELECT id FROM posts limit 0, 5;

最后你跑了:

select p.id, c.id from posts p left join comments c on c.post_id = p.id where id in(id list from above query)

显然,您的查询不会遇到上述问题。但我只是想说明为什么在一个单独的查询中获得总计数可能会很好。