Recuento de filas con DOP


Hay muchas declaraciones contradictorias alrededor. ¿Cuál es la mejor manera de contar filas usando PDO en PHP? Antes de usar PDO, simplemente usé mysql_num_rows.

fetchAll es algo que no quiero porque a veces puedo estar tratando con grandes conjuntos de datos, por lo que no es bueno para mi uso.

¿Tiene alguna sugerencia?

 158
Author: Sᴀᴍ Onᴇᴌᴀ, 2009-05-19

21 answers

$sql = "SELECT count(*) FROM `table` WHERE foo = bar"; 
$result = $con->prepare($sql); 
$result->execute(); 
$number_of_rows = $result->fetchColumn(); 

No es la forma más elegante de hacerlo, además de que implica una consulta adicional.

PDO tiene PDOStatement::rowCount(), que aparentemente no funciona en MySQL. Qué dolor.

De la DOP Doc:

Para la mayoría de las bases de datos, PDOStatement:: rowCount () no devuelve el número de filas afectadas por una instrucción SELECT. En su lugar, use PDO:: query() para emitir un SELECT COUNT(*) con la misma predicados como su SELECCIÓN prevista declaración, luego use PDOStatement:: fetchColumn () to recuperar el número de filas que se ser devuelto. Su aplicación puede entonces realice la acción correcta.

EDITAR: El ejemplo de código anterior utiliza una instrucción preparada, que en muchos casos es probablemente innecesaria con el propósito de contar filas, por lo que:

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;
 221
Author: karim79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-30 14:50:25

Como escribí anteriormente en una respuesta a una pregunta similar, la única razón por la que mysql_num_rows() funcionó es porque estaba obteniendo internamente todas las filas para darle esa información, incluso si no lo parecía a usted.

Así que en PDO, sus opciones son:

  1. Usar MySQL FOUND_ROWS() función.
  2. Use DOP fetchAll() función para obtener todas las filas en una matriz, luego use count() en ella.
  3. Haga una consulta adicional a SELECT COUNT(*), como karim79 sugerir.
 77
Author: Chad Birch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:36

Esto es súper tarde, pero me encontré con el problema y hago esto:

function countAll($table){
   $dbh = dbConnect();
   $sql = "select * from `$table`";

   $stmt = $dbh->prepare($sql);
    try { $stmt->execute();}
    catch(PDOException $e){echo $e->getMessage();}

return $stmt->rowCount();

Es realmente simple, y fácil. :)

 19
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-06 07:15:51

Antes de usar la DOP simplemente usé mysql_num_rows().

Usted no debería haberlo estado usando en primer lugar.

mysql_num_rows(), así como PDOStatement::rowCount() implica que ya está seleccionado sus datos. En este caso, solo hay dos casos de uso posibles para dicha función:

  1. Estaba seleccionando sus datos solo para obtener el recuento.
  2. Desea saber si su consulta devolvió alguna fila.

Y el primero nunca debe usarse. Nunca se deben seleccionar filas para contarlas, ya que su servidor puede atragantarse debido al gran conjunto de datos devuelto.

Además, seleccionar filas solo para contarlas simplemente no tiene sentido. Se debe ejecutar una consulta count(*), con solo una fila devuelta.

El segundo caso de uso es menos desastroso pero más bien inútil:en caso de que necesite saber si su consulta devolvió algún dato, ¡siempre tendrá los datos en sí!

Decir, si usted están seleccionando solo una fila, luego solo tráigala y verifique el resultado:

$stmt->execute();
$row = $stmt->fetch();
if ($row) { // here! as simple as that
}

En caso de que necesite obtener muchas filas, puede usar fetchAll().

fetchAll() es algo que no quiero, ya que a veces puedo estar tratando con grandes conjuntos de datos

Tenga en cuenta que en una aplicación web nunca debe seleccionar una gran cantidad de filas. Solo se deben seleccionar las filas que se usarán realmente en una página web. Para lo cual se debe usar una cláusula LIMIT o similar en SQL. Y para una cantidad tan moderada de datos que está bien usar fetchAll()

En un caso tan raro cuando necesita seleccionar una gran cantidad real de filas (en una aplicación de consola, por ejemplo), para reducir la cantidad de memoria utilizada, debe usar una consulta sin búfer, pero en este caso rowCount() no estará disponible de todos modos, por lo que no hay uso para esta función también.

Así que ya ves, no hay caso de uso ni para rowCount() ni para una consulta adicional para sustituirlo, como se sugiere en la respuesta aceptada.

 18
Author: Your Common Sense,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-27 04:53:30

Terminé usando esto:

$result = $db->query($query)->fetchAll();

if (count($result) > 0) {
    foreach ($result as $row) {
        echo $row['blah'] . '<br />';
    }
} else {
    echo "<p>Nothing matched your query.</p>";
}
 16
Author: Eric Warnke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-31 17:05:48

Este post es antiguo, pero Obtener el recuento de filas en php con PDO es simple

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
 7
Author: TenTen Peter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-23 00:31:06

Este es un post antiguo, pero frustrado buscando alternativas. Es muy desafortunado que PDO carezca de esta característica, especialmente porque PHP y MySQL tienden a ir de la mano.

Hay un error desafortunado al usar fetchColumn() ya que ya no puede usar ese conjunto de resultados (efectivamente) cuando fetchColumn() mueve la aguja a la siguiente fila. Así, por ejemplo, si usted tiene un resultado similar a

  1. Fruta->Plátano
  2. Fruta- > Manzana
  3. Fruta->Naranja

Si usa fetchColumn() puede descubrir que hay 3 frutas devueltas, pero si ahora recorre el resultado, solo tiene dos columnas, el precio de fetchColumn() es la pérdida de la primera columna de resultados solo para averiguar cuántas filas se devolvieron. Eso conduce a una codificación descuidada y a resultados totalmente cargados de errores si se implementa.

Así que ahora, usando fetchColumn () tienes que implementar y llamada completamente nueva y consulta MySQL solo para obtener un conjunto de resultados de trabajo fresco. (que con suerte no ha cambiado desde su última consulta), lo sé, poco probable, pero puede suceder. Además, la sobrecarga de consultas duales en toda la validación de recuento de filas. Lo que para este ejemplo es pequeño, pero analizar 2 millones de filas en una consulta unida, no es un precio agradable a pagar.

Me encanta PHP y apoyo a todos los involucrados en su desarrollo, así como a la comunidad en general usando PHP a diario, pero realmente espero que esto sea se abordarán en futuras versiones. Esta es 'realmente' mi única queja con PHP PDO, que de lo contrario es una gran clase.

 5
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-14 02:29:47

Responder a esto porque me atrapé con él ahora sabiendo esto y tal vez sea útil.

Tenga en cuenta que no puede obtener resultados dos veces. Usted tiene que guardar el resultado fetch en array, obtener el recuento de filas por count($array), y los resultados de salida con foreach. Por ejemplo:

$query = "your_query_here";
$STH = $DBH->prepare($query);
$STH->execute();
$rows = $STH->fetchAll();
//all your results is in $rows array
$STH->setFetchMode(PDO::FETCH_ASSOC);           
if (count($rows) > 0) {             
    foreach ($rows as $row) {
        //output your rows
    }                       
}
 2
Author: csharp newbie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 06:01:44

Si solo desea obtener un recuento de filas (no los datos), es decir. usando COUNT (*) en una instrucción preparada, todo lo que necesita hacer es recuperar el resultado y leer el valor:

$sql = "SELECT count(*) FROM `table` WHERE foo = bar";
$statement = $con->prepare($sql); 
$statement->execute(); 
$count = $statement->fetch(PDO::FETCH_NUM); // Return array indexed by column number
return reset($count); // Resets array cursor and returns first value (the count)

En realidad recuperar todas las filas (datos) para realizar un recuento simple es un desperdicio de recursos. Si el conjunto de resultados es grande, su servidor puede atragantarse con él.

 1
Author: madfish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-11 09:16:24

Echa un vistazo a este enlace: http://php.net/manual/en/pdostatement.rowcount.php No se recomienda usar rowCount() en las instrucciones SELECT!

 1
Author: Reza Neghabi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 04:19:34

Cuando se trata de mysql cómo contar o obtener cuántas filas en una tabla con PHP PDO uso esto

// count total number of rows
$query = "SELECT COUNT(*) as total_rows FROM sometable";
$stmt = $con->prepare($query);

// execute query
$stmt->execute();

// get total rows
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total_rows = $row['total_rows'];

Los créditos van a Mike @ codeofaninja.com

 0
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-12 14:53:37

Aquí hay una extensión personalizada de la clase PDO, con una función auxiliar para recuperar el número de filas incluidas por el criterio "WHERE" de la última consulta.

Sin embargo, es posible que necesite agregar más 'manejadores', dependiendo de los comandos que use. En este momento solo funciona para consultas que usan "FROM" o "UPDATE ".

class PDO_V extends PDO
{
    private $lastQuery = null;

    public function query($query)
    {
        $this->lastQuery = $query;    
        return parent::query($query);
    }
    public function getLastQueryRowCount()
    {
        $lastQuery = $this->lastQuery;
        $commandBeforeTableName = null;
        if (strpos($lastQuery, 'FROM') !== false)
            $commandBeforeTableName = 'FROM';
        if (strpos($lastQuery, 'UPDATE') !== false)
            $commandBeforeTableName = 'UPDATE';

        $after = substr($lastQuery, strpos($lastQuery, $commandBeforeTableName) + (strlen($commandBeforeTableName) + 1));
        $table = substr($after, 0, strpos($after, ' '));

        $wherePart = substr($lastQuery, strpos($lastQuery, 'WHERE'));

        $result = parent::query("SELECT COUNT(*) FROM $table " . $wherePart);
        if ($result == null)
            return 0;
        return $result->fetchColumn();
    }
}
 -1
Author: Venryx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-15 08:32:20

Una línea rápida para obtener la primera entrada devuelta. Esto es bueno para consultas muy básicas.

<?php
$count = current($db->query("select count(*) from table")->fetch());
?>

Referencia

 -1
Author: itsazzad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-02 12:57:19

Probé $count = $stmt->rowCount(); con Oracle 11.2 y no funcionó. Decidí utilizar un bucle for como se muestra a continuación.

   $count =  "";
    $stmt =  $conn->prepare($sql);
    $stmt->execute();
   echo "<table border='1'>\n";
   while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
        $count++;
        echo "<tr>\n";
    foreach ($row as $item) {
    echo "<td class='td2'>".($item !== null ? htmlentities($item, ENT_QUOTES):"&nbsp;")."</td>\n";
        } //foreach ends
        }// while ends
        echo "</table>\n";
       //echo " no of rows : ". oci_num_rows($stmt);
       //equivalent in pdo::prepare statement
       echo "no.of rows :".$count;
 -1
Author: manas mukherjee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-21 11:02:52

Para consultas directas donde quiero una fila específica, y quiero saber si se encontró, uso algo como:

function fetchSpecificRow(&$myRecord) {
    $myRecord = array();
    $myQuery = "some sql...";
    $stmt = $this->prepare($myQuery);
    $stmt->execute(array($parm1, $parm2, ...));
    if ($myRecord = $stmt->fetch(PDO::FETCH_ASSOC)) return 0;
    return $myErrNum;
}
 -1
Author: user5862537,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-31 00:20:49

Function count_x($conexion) { $consulta = " SELECT * FROM tbl where id = '0' "; $sentencia = $conexion->prepare($consulta); $instrucción->execute(); $total_rows = $instrucción->rowCount(); return $total_rows; }

 -1
Author: alpazull,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-11 06:22:05

Cuando haces un RECUENTO (*) en tu sentencia mysql como en

$q = $db->query("SELECT COUNT(*) FROM ...");

Su consulta mysql ya está contando el número de resultados ¿por qué contar de nuevo en php? para obtener el resultado de su mysql

$q = $db->query("SELECT COUNT(*) as counted FROM ...");
$nb = $q->fetch(PDO::FETCH_OBJ);
$nb = $nb->counted;

Y $nb contendrán el entero que ha contado con su sentencia mysql un poco largo para escribir pero rápido para ejecutar

Editar: lo siento por el post equivocado, pero como algunos ejemplos muestran la consulta con count in, estaba sugiriendo el uso del resultado de mysql, pero si no utiliza el count in sql fetchAll () es eficiente, si guardas el resultado en una variable no perderás una línea.

$data = $dbh->query("SELECT * FROM ...");
$table = $data->fetchAll(PDO::FETCH_OBJ);

count($table) devolverá el número de fila y aún puede usar el resultado después de como $row = $table[0] o usando un foreach

foreach($table as $row){
  print $row->id;
}
 -2
Author: Surpriserom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-30 09:31:24

Puede combinar el mejor método en una línea o función, y tener la nueva consulta generada automáticamente para usted:

function getRowCount($q){ 
    global $db;
    return $db->query(preg_replace('/SELECT [A-Za-z,]+ FROM /i','SELECT count(*) FROM ',$q))->fetchColumn();
}

$numRows = getRowCount($query);
 -2
Author: Bryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-26 23:25:21
$qry = "select * from tabel";
$cmd = $conn->prepare($qry);
$cmd->execute();
$cmd->rowCount()
 -2
Author: Dika Purnasucita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-31 06:10:03
<table>
      <thead>
           <tr>
                <th>Sn.</th>
                <th>Name</th>
           </tr>
      </thead>
      <tbody>
<?php
     $i=0;
     $statement = $db->prepare("SELECT * FROM tbl_user ORDER BY name ASC");
     $statement->execute();
     $result = $statement->fetchColumn();
     foreach($result as $row) {
        $i++;
    ?>  
      <tr>
         <td><?php echo $i; ?></td>
         <td><?php echo $row['name']; ?></td>
      </tr>
     <?php
          }
     ?>
     </tbody>
</table>
 -2
Author: Amranur Rahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-09 09:45:36

Use el parámetro array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), de lo contrario muestre -1:

Usan parametro array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), sin ello sale -1

Ejemplo:

$res1 = $mdb2->prepare("SELECT clave FROM $tb WHERE id_usuario='$username' AND activo=1 and id_tipo_usuario='4'", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$res1->execute();

$count=$res1->rowCount();
echo $count;
 -3
Author: Victor Idrogo Aliaga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-23 23:46:28