php判断查询结果行数,php-如何获取GROUP BY查询的总行数?

php-如何获取GROUP BY查询的总行数?

从PDO手册中:

PDOStatement :: rowCount()返回 最后一个受影响的行数 DELETE,INSERT或UPDATE语句 由相应的执行 PDOStatement对象。

如果最后一条SQL语句执行 关联的PDOStatement是 SELECT语句,某些数据库可能 返回返回的行数 那句话。 但是这个 行为并不能完全保证 数据库,不应该依赖 用于便携式应用。

我是最近才发现的。 我刚刚将数据库抽象层更改为不再使用SELECT ... FROM,因为仅查询实际行然后对结果进行计数将更加有效。 现在PDO不支持!!

我不将PDO用于MySQL和PgSQL,但用于SQLite。 有没有办法(不完全改变dbal的后退)在PDO中对这样的行进行计数? 在MySQL中,将如下所示:

$q = $db->query('SELECT a, b, c FROM tbl WHERE oele = 2 GROUP BY boele');

$rows = $q->num_rows;

// and now use $q to get actual data

使用MySQLi和PgSQL驱动程序,这是可能的。 对于所有PDO,不是!?

PS。 我最初的解决方案是扩展SQLResult-> count方法(我自己的方法),用SELECT COUNT(1) FROM替换SELECT ... FROM,然后仅返回该数字(效率很低,但仅适用于SQLite PDO)。 不过,这还不够好,因为在上面的示例查询中是GROUP BY,这将更改COUNT(1)的含义/功能。

Rudie asked 2020-07-21T17:40:19Z

11个解决方案

44 votes

这是给您的解决方案

$sql="SELECT count(*) FROM [tablename] WHERE key == ? ";

$sth = $this->db->prepare($sql);

$sth->execute(array($key));

$rows = $sth->fetch(PDO::FETCH_NUM);

echo $rows[0];

RoboTamer answered 2020-07-21T17:40:29Z

24 votes

这有点内存不足,但是如果您仍在使用数据,我会经常使用它:

$rows = $q->fetchAll();

$num_rows = count($rows);

mjec answered 2020-07-21T17:40:49Z

8 votes

我最终使用的方法非常简单:

$query = 'SELECT a, b, c FROM tbl WHERE oele = 2 GROUP BY boele';

$nrows = $db->query("SELECT COUNT(1) FROM ($query) x")->fetchColumn();

可能不是最有效的方法,但它似乎是万无一失的,因为它实际上可以计算原始查询的结果。

Rudie answered 2020-07-21T17:41:14Z

4 votes

我不将PDO用于MySQL和PgSQL,但用于SQLite。 有没有办法(不完全改变dbal的后退)在PDO中对这样的行进行计数?

根据此评论,SQLite问题是由3.x中的API更改引入的。

就是说,您可能需要在使用PDO之前检查其实际实现功能。

我不熟悉它的内部结构,但对于PDO解析您的SQL(因为在数据库的日志中会出现SQL语法错误)的想法我会感到怀疑,更不用说试图对它做一点丝毫的意义以便计算行数了 使用最佳策略。

假设并非如此,要在select语句中返回所有适用行的计数的现实策略包括在SQL语句中对操作limit子句进行字符串操作,以及以下两种方法之一:

在其上运行select count()作为子查询(从而避免了您在PS中描述的问题);

打开一个游标,运行全部获取并计算行数; 要么

首先打开了这样一个游标,然后类似地计算剩余的行。

但是,更好的计数方法是执行完全优化的查询。 通常,这意味着重写您尝试分页的初始查询中有意义的部分-通过操作等去除不需要的字段和顺序。

最后,如果您的数据集足够大,可以计算任何类型的滞后,您可能还想研究返回从统计信息中得出的估计值,和/或定期将结果缓存在Memcache中。 在某些时候,精确地计数已经不再有用...

Denis de Bernardy answered 2020-07-21T17:42:15Z

2 votes

请记住,PDOStatement是Traversable。给定查询:

$query = $dbh->query('

SELECT

*

FROM

test

');

可以迭代以下内容:

$it = new IteratorIterator($query);

echo '

', iterator_count($it), ' items

';

// Have to run the query again unfortunately

$query->execute();

foreach ($query as $row) {

echo '

', $row['title'], '

';

}

或者,您可以执行以下操作:

$it = new IteratorIterator($query);

$it->rewind();

if ($it->valid()) {

do {

$row = $it->current();

echo '

', $row['title'], '

';

$it->next();

} while ($it->valid());

} else {

echo '

No results

';

}

Nev Stokes answered 2020-07-21T17:42:44Z

2 votes

如果您愿意放弃抽象的提示,则可以使用自定义包装器类,该类将所有内容直接传递给PDO。 说,像这样:(警告,未经测试的代码)

class SQLitePDOWrapper

{

private $pdo;

public function __construct( $dns, $uname = null, $pwd = null, $opts = null )

{

$this->pdo = new PDO( $dns, $unam, $pwd, $opts );

}

public function __call( $nm, $args )

{

$ret = call_user_func_array( array( $this->pdo, $nm ), $args );

if( $ret instanceof PDOStatement )

{

return new StatementWrapper( $this, $ret, $args[ 0 ] );

// I'm pretty sure args[ 0 ] will always be your query,

// even when binding

}

return $ret;

}

}

class StatementWrapper

{

private $pdo; private $stat; private $query;

public function __construct( PDO $pdo, PDOStatement $stat, $query )

{

$this->pdo = $pdo;

$this->stat = $stat;

this->query = $query;

}

public function rowCount()

{

if( strtolower( substr( $this->query, 0, 6 ) ) == 'select' )

{

// replace the select columns with a simple 'count(*)

$res = $this->pdo->query(

'SELECT COUNT(*)' .

substr( $this->query,

strpos( strtolower( $this->query ), 'from' ) )

)->fetch( PDO::FETCH_NUM );

return $res[ 0 ];

}

return $this->stat->rowCount();

}

public function __call( $nm, $args )

{

return call_user_func_array( array( $this->stat, $nm ), $args );

}

}

cwallenpoole answered 2020-07-21T17:43:04Z

1 votes

也许这将为您解决问题?

$FoundRows = $DataObject->query('SELECT FOUND_ROWS() AS Count')->fetchColumn();

tradyblix answered 2020-07-21T17:43:24Z

0 votes

您必须使用rowCount —返回受最后一条SQL语句影响的行数

$query = $dbh->prepare("SELECT * FROM table_name");

$query->execute();

$count =$query->rowCount();

echo $count;

Rahul Saxena answered 2020-07-21T17:43:44Z

0 votes

将查询结果放入数组中,可以执行count($ array)并在之后使用查询结果行呢? 例:

$sc='SELECT * FROM comments';

$res=array();

foreach($db->query($sc) as $row){

$res[]=$row;

}

echo "num rows: ".count($res);

echo "Select output:";

foreach($res as $row){ echo $row['comment'];}

XaviQV answered 2020-07-21T17:44:04Z

0 votes

这是另一个问题,错误地提出了很多可怕的解决方案,所有这些问题都使解决一个不存在的问题变得极为复杂。

任何数据库交互的极其简单和明显的规则是

始终选择所需的唯一数据。

从这个角度来看,问题是错误的,接受的答案是正确的。 但是其他建议的解决方案也很糟糕。

问题是“如何错误地计数”。 一个人永远都不要直接回答这个问题,相反,唯一正确的答案是“一个人永远不要选择要对行进行计数的行。相反,总是请数据库为您对行进行计数。” 这个规则是如此明显,以至于无法看到如此多的尝试来打破它。

学习了此规则后,我们将看到这是一个SQL问题,甚至与PDO无关。 而且,如果从SQL角度正确地提出问题,答案将立即出现-DISTINCT。

$num = $db->query('SELECT count(distinct boele) FROM tbl WHERE oele = 2')->fetchColumn();

是这个特定问题的正确答案。

从上述规则的角度来看,开幕式海报本身的解决方案也是可以接受的,但总体而言效率较低。

Your Common Sense answered 2020-07-21T17:44:56Z

-1 votes

您可以通过两种方式来计算行数。

$query = "SELECT count(*) as total from table1";

$prepare = $link->prepare($query);

$prepare->execute();

$row = $prepare->fetch(PDO::FETCH_ASSOC);

echo $row['total']; // This will return you a number of rows.

或者第二种方式是

$query = "SELECT field1, field2 from table1";

$prepare = $link->prepare($query);

$prepare->execute();

$row = $prepare->fetch(PDO::FETCH_NUM);

echo $rows[0]; // This will return you a number of rows as well.

php-coder answered 2020-07-21T17:45:20Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值