简体   繁体   English

如何计算 MySQL 查询返回的行数?

[英]How can I count the numbers of rows that a MySQL query returned?

如何计算 MySQL 查询返回的行数?

Getting total rows in a query result...获取查询结果中的总行数...

You could just iterate the result and count them.你可以迭代结果并计算它们。 You don't say what language or client library you are using, but the API does provide a mysql_num_rows function which can tell you the number of rows in a result.你没有说你正在使用什么语言或客户端库,但 API 确实提供了一个mysql_num_rows函数,它可以告诉你结果中的行数。

This is exposed in PHP, for example, as the mysqli_num_rows function.这在 PHP 中公开,例如,作为mysqli_num_rows函数。 As you've edited the question to mention you're using PHP, here's a simple example using mysqli functions:当您编辑问题以提及您正在使用 PHP 时,这是一个使用 mysqli 函数的简单示例:

$link = mysqli_connect("localhost", "user", "password", "database");

$result = mysqli_query($link, "SELECT * FROM table1");
$num_rows = mysqli_num_rows($result);

echo "$num_rows Rows\n";

Getting a count of rows matching some criteria...获取符合某些条件的行数...

Just use COUNT(*) - see Counting Rows in the MySQL manual.只需使用 COUNT(*) - 请参阅 MySQL 手册中的Counting Rows For example:例如:

SELECT COUNT(*) FROM foo WHERE bar= 'value';

Get total rows when LIMIT is used...使用 LIMIT 时获取总行数...

If you'd used a LIMIT clause but want to know how many rows you'd get without it, use SQL_CALC_FOUND_ROWS in your query, followed by SELECT FOUND_ROWS();如果您使用了 LIMIT 子句但想知道没有它会得到多少行,请在查询中使用SQL_CALC_FOUND_ROWS ,然后是 SELECT FOUND_ROWS();

SELECT SQL_CALC_FOUND_ROWS * FROM foo
   WHERE bar="value" 
   LIMIT 10;

SELECT FOUND_ROWS();

For very large tables, this isn't going to be particularly efficient, and you're better off running a simpler query to obtain a count and caching it before running your queries to get pages of data.对于非常大的表,这不会特别有效,您最好先运行一个更简单的查询来获取计数并缓存它,然后再运行查询以获取数据页。

如果您必须使用简单的 SQL 来解决问题,您可以使用内联视图。

select count(*) from (select * from foo) as x;

If your SQL query has a LIMIT clause and you want to know how many results total are in that data set you can use SQL_CALC_FOUND_ROWS followed by SELECT FOUND_ROWS();如果您的 SQL 查询有一个LIMIT子句,并且您想知道该数据集中总共有多少结果,您可以使用SQL_CALC_FOUND_ROWS后跟SELECT FOUND_ROWS(); This returns the number of rows A LOT more efficiently than using COUNT(*)这比使用COUNT(*)更有效地返回行数
Example (straight from MySQL docs):示例(直接来自 MySQL 文档):

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();
SELECT SQL_CALC_FOUND_ROWS *
FROM   table1
WHERE  ...;

SELECT FOUND_ROWS();

FOUND_ROWS() must be called immediately after the query. FOUND_ROWS()必须在查询后立即调用。

Use 2 queries as below, One to fetch the data with limit and other to get the no of total matched rows.使用以下 2 个查询,一个用于获取有限制的数据,另一个用于获取总匹配行数。

Ex:前任:

SELECT * FROM tbl_name WHERE id > 1000 LIMIT 10;
SELECT COUNT(*) FROM tbl_name WHERE id > 1000;

As described by Mysql guide , this is the most optimized way, and also SQL_CALC_FOUND_ROWS query modifier and FOUND_ROWS() function are deprecated as of MySQL 8.0.17Mysql guide所述,这是最优化的方式,并且SQL_CALC_FOUND_ROWS查询修饰符和FOUND_ROWS()函数自 MySQL 8.0.17 起已弃用

The basics基础知识

To get the number of matching rows in SQL you would usually use COUNT(*) .要获取 SQL 中匹配的行数,您通常会使用COUNT(*) For example:例如:

SELECT COUNT(*) FROM some_table

To get that in value in PHP you need to fetch the value from the first column in the first row of the returned result.要在 PHP 中获取该值,您需要从返回结果的第一行的第一列中获取值。 An example using PDO and mysqli is demonstrated below.下面演示了一个使用 PDO 和 mysqli 的示例。

However, if you want to fetch the results and then still know how many records you fetched using PHP, you could use count() or avail of the pre-populated count in the result object if your DB API offers it eg mysqli's num_rows .但是,如果您想获取结果并且仍然知道您使用 PHP 获取了多少条记录,您可以使用count()或使用结果对象中的预填充计数,如果您的 DB API 提供它,例如mysqli 的num_rows

Using MySQLi使用 MySQLi

Using mysqli you can fetch the first row using fetch_row() and then access the 0 column, which should contain the value of COUNT(*) .使用 mysqli,您可以使用fetch_row()获取第一行,然后访问0列,该列应包含COUNT(*)的值。

// your connection code
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new \mysqli('localhost', 'dbuser', 'yourdbpassword', 'db_name');
$mysqli->set_charset('utf8mb4');

// your SQL statement
$stmt = $mysqli->prepare('SELECT COUNT(*) FROM some_table WHERE col1=?');
$stmt->bind_param('s', $someVariable);
$stmt->execute();
$result = $stmt->get_result();

// now fetch 1st column of the 1st row 
$count = $result->fetch_row()[0];

echo $count;

If you want to fetch all the rows, but still know the number of rows then you can use num_rows or count() .如果您想获取所有行,但仍然知道行数,那么您可以使用num_rowscount()

// your SQL statement
$stmt = $mysqli->prepare('SELECT col1, col2 FROM some_table WHERE col1=?');
$stmt->bind_param('s', $someVariable);
$stmt->execute();
$result = $stmt->get_result();

// If you want to use the results, but still know how many records were fetched
$rows = $result->fetch_all(MYSQLI_ASSOC);

echo $result->num_rows;
// or
echo count($rows);

Using PDO使用 PDO

Using PDO is much simpler.使用 PDO 要简单得多。 You can directly call fetchColumn() on the statement to get a single column value.您可以直接在语句上调用fetchColumn()以获取单个列值。

// your connection code
$pdo = new \PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'root', '', [
    \PDO::ATTR_EMULATE_PREPARES => false,
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
]);

// your SQL statement
$stmt = $pdo->prepare('SELECT COUNT(*) FROM some_table WHERE col1=?');
$stmt->execute([
    $someVariable
]);

// Fetch the first column of the first row
$count = $stmt->fetchColumn();

echo $count;

Again, if you need to fetch all the rows anyway, then you can get it using count() function.同样,如果您无论如何都需要获取所有行,那么您可以使用count()函数来获取它。

// your SQL statement
$stmt = $pdo->prepare('SELECT col1, col2 FROM some_table WHERE col1=?');
$stmt->execute([
    $someVariable
]);

// If you want to use the results, but still know how many records were fetched
$rows = $stmt->fetchAll();

echo count($rows);

PDO's statement doesn't offer pre-computed property with the number of rows fetched, but it has a method called rowCount() . PDO 的语句不提供带有获取的行数的预计算属性,但它有一个名为rowCount()的方法。 This method can tell you the number of rows returned in the result, but it cannot be relied upon and it is generally not recommended to use.此方法可以告诉您结果中返回的行数,但不能依赖,一般不建议使用。

If you want the result plus the number of rows returned do something like this.如果您想要结果加上返回的行数,请执行以下操作。 Using PHP.使用 PHP。

$query = "SELECT * FROM Employee";
$result = mysql_query($query);
echo "There are ".mysql_num_rows($result)." Employee(s).";

Assuming you're using the mysql_ or mysqli_ functions, your question should already have been answered by others.假设您正在使用 mysql_ 或 mysqli_ 函数,您的问题应该已经被其他人回答了。

However if you're using PDO, there is no easy function to return the number of rows retrieved by a select statement, unfortunately.但是,如果您使用的是 PDO,不幸的是,没有简单的函数可以返回 select 语句检索到的行数。 You have to use count() on the resultset (after assigning it to a local variable, usually).您必须在结果集上使用 count() (通常在将其分配给局部变量之后)。

Or if you're only interested in the number and not the data, PDOStatement::fetchColumn() on your SELECT COUNT(1)... result.或者,如果您只对数字感兴趣,而不对数据感兴趣,请在 SELECT COUNT(1)... 结果中使用 PDOStatement::fetchColumn()。

If you're fetching data using Wordpress, then you can access the number of rows returned using $wpdb->num_rows:如果您使用 Wordpress 获取数据,那么您可以使用 $wpdb->num_rows 访问返回的行数:

$wpdb->get_results( $wpdb->prepare('select * from mytable where foo = %s', $searchstring));
echo $wpdb->num_rows;

If you want a specific count based on a mysql count query then you do this:如果您想要基于 mysql 计数查询的特定计数,那么您可以这样做:

$numrows = $wpdb->get_var($wpdb->prepare('SELECT COUNT(*) FROM mytable where foo = %s', $searchstring );
echo $numrows;

If you're running updates or deletes then the count of rows affected is returned directly from the function call:如果您正在运行更新或删除,则直接从函数调用返回受影响的行数:

$numrowsaffected = $wpdb->query($wpdb->prepare(
   'update mytable set val=%s where myid = %d', $valuetoupdate, $myid));

This applies also to $wpdb->update and $wpdb->delete.这也适用于 $wpdb->update 和 $wpdb->delete。

As it is 2015, and deprecation of mysql_* functionality, this is a PDO -only visualization.由于是 2015 年,并且mysql_*功能已弃用,因此这是仅PDO的可视化。

<?php
    // Begin Vault (this is in a vault, not actually hard-coded)
    $host="hostname";
    $username="GuySmiley";
    $password="thePassword";
    $dbname="dbname";
    // End Vault

    $b='</br>';
    try {
        $theCategory="fruit";   // value from user, hard-coded here to get one in

        $dbh = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // prepared statement with named placeholders
        $stmt = $dbh->prepare("select id,foodName from foods where category=:theCat and perishable=1");
        $stmt->bindParam(':theCat', $theCategory, PDO::PARAM_STR,20);
        $stmt->execute();
        echo "rowCount() returns: ".$stmt->rowCount().$b;   // See comments below from the Manual, varies from driver to driver

        $stmt = $dbh->prepare("select count(*) as theCount from foods where category=:theCat and perishable=1");
        $stmt->bindParam(':theCat', $theCategory, PDO::PARAM_STR,20);
        $stmt->execute();
        $row=$stmt->fetch();    // fetches just one row, which is all we expect
        echo "count(*) returns: ".$row['theCount'].$b;

        $stmt = null;
        // PDO closes connection at end of script
    } catch (PDOException $e) {
        echo 'PDO Exception: ' . $e->getMessage();
        exit();
    }
?>

Schema for testing用于测试的架构

create table foods
(   id int auto_increment primary key,
    foodName varchar(100) not null,
    category varchar(20) not null,
    perishable int not null
);
insert foods (foodName,category,perishable) values 
('kiwi','fruit',1),('ground hamburger','meat',1),
('canned pears','fruit',0),('concord grapes','fruit',1);

For my implementation, I get the output of 2 for both echos above.对于我的实现,对于上面的两个echos ,我得到了2的输出。 The purpose of the above 2 strategies is to determine if your driver implementation emits the rowCount, and if not, to seek a fall-back strategy.上述 2 种策略的目的是确定您的驱动程序实现是否发出 rowCount,如果没有,则寻求备用策略。

From the Manual on PDOStatement::rowCount :来自PDOStatement::rowCount手册:

PDOStatement::rowCount() returns the number of rows affected by a DELETE, INSERT, or UPDATE statement. PDOStatement::rowCount() 返回受 DELETE、INSERT 或 UPDATE 语句影响的行数。

For most databases , PDOStatement::rowCount() does not return the number of rows affected by a SELECT statement. For most databases ,PDOStatement::rowCount() 不返回受 SELECT 语句影响的行数。 Instead, use PDO::query() to issue a SELECT COUNT(*) statement with the same predicates as your intended SELECT statement, then use PDOStatement::fetchColumn() to retrieve the number of rows that will be returned.相反,使用 PDO::query() 发出 SELECT COUNT(*) 语句,其谓词与预期的 SELECT 语句相同,然后使用 PDOStatement::fetchColumn() 检索将返回的行数。 Your application can then perform the correct action.然后,您的应用程序可以执行正确的操作。

This is not a direct answer to the question, but in practice I often want to have an estimate of the number of rows that will be in the result set.这不是问题的直接答案,但在实践中,我经常希望估计结果集中的行数。 For most type of queries, MySQL's "EXPLAIN" delivers that.对于大多数类型的查询,MySQL 的“EXPLAIN”提供了这一点。

I for example use that to refuse to run a client query if the explain looks bad enough.例如,如果解释看起来足够糟糕,我会使用它来拒绝运行客户端查询。

Then also daily run "ANALYZE LOCAL TABLE" (outside of replication, to prevent cluster locks) on your tables, on each involved MySQL server.然后每天在每个涉及的 MySQL 服务器上的表上运行“分析本地表”(在复制之外,以防止集群锁定)。

> SELECT COUNT(*) AS total FROM foo WHERE bar= 'value';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM