Zeilenanzahl mit gU


192

Es gibt viele widersprüchliche Aussagen. Was ist der beste Weg, um die Zeilenanzahl mit PDO in PHP zu zählen? Vor der Verwendung von PDO habe ich einfach verwendet mysql_num_rows.

fetchAll ist etwas, das ich nicht will, weil ich manchmal mit großen Datenmengen zu tun habe, also nicht gut für meine Verwendung.

Hast du irgendwelche Vorschläge?

Antworten:


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

Dies ist nicht die eleganteste Methode und erfordert eine zusätzliche Abfrage.

PDO hat PDOStatement::rowCount(), was anscheinend in MySql nicht funktioniert. Was für ein Schmerz.

Aus dem PDO-Dokument:

Bei den meisten Datenbanken gibt PDOStatement :: rowCount () nicht die Anzahl der Zeilen zurück, die von einer SELECT-Anweisung betroffen sind. Verwenden Sie stattdessen PDO :: query (), um eine SELECT COUNT (*) -Anweisung mit denselben Prädikaten wie Ihre beabsichtigte SELECT-Anweisung auszugeben, und verwenden Sie dann PDOStatement :: fetchColumn (), um die Anzahl der zurückgegebenen Zeilen abzurufen. Ihre Anwendung kann dann die richtige Aktion ausführen.

BEARBEITEN: Das obige Codebeispiel verwendet eine vorbereitete Anweisung, die in vielen Fällen zum Zählen von Zeilen wahrscheinlich nicht erforderlich ist.

$nRows = $pdo->query('select count(*) from blah')->fetchColumn(); 
echo $nRows;

Dies würde bedeuten, eine zusätzliche Datenbankabfrage durchzuführen. Ich gehe davon aus, dass er bereits eine Auswahlabfrage durchgeführt hat und nun wissen möchte, wie viele Zeilen zurückgegeben wurden.
Nickf

1
Nickf ist richtig. mysql_num_rows () funktioniert bei Verwendung von PDO nicht, oder?
James

Es stimmt, anscheinend gibt es PDOStatement :: rowCount (), aber das funktioniert nicht in MySql
karim79

11
Gibt bei diesem Ansatz fetchColumn()eine Zeichenfolge "1234" zurück ... Ihre EDIT hat echo count($nRows);- count()ist eine Array-Funktion: P. Ich würde auch empfehlen, das Ergebnis fetchColumn()in eine Ganzzahl umzuwandeln. $count = (int) $stmt->fetchColumn()
Cobby

1
@ karim79 Der Ansatz der nicht vorbereiteten Anweisung gibt nur 1 anstelle der tatsächlichen Anzahl von Zeilen zurück. Die vorbereitete Anweisung funktioniert gut. Was kann das Problem sein?
SilentAssassin

86

Wie ich zuvor in einer Antwort auf eine ähnliche Frage geschrieben habe , hat der einzige Grund mysql_num_rows()funktioniert, weil intern alle Zeilen abgerufen wurden, um Ihnen diese Informationen zu geben, auch wenn es Ihnen nicht so erschien.

In PDO haben Sie folgende Möglichkeiten:

  1. Verwenden Sie die MySQL- FOUND_ROWS()Funktion.
  2. Verwenden Sie die PDO- fetchAll()Funktion, um alle Zeilen in ein Array abzurufen, und verwenden Sie count()sie dann.
  3. SELECT COUNT(*)Führen Sie eine zusätzliche Abfrage an , wie von karim79 vorgeschlagen.

8
Vielen Dank, dass Sie mich über mysql_num_rows () aufgeklärt haben. Dies scheint ein wichtiger Engpass zu sein, den ich mir selbst gegeben habe. Danke noch einmal.
James

2
fetch_all ist eigentlich fetchAll () :)
dynamisch

2
Option 2 ist nicht ratsam, wenn das Ergebnis groß ist.
Edson Horacio Junior

FOUND_ROWS () wird aus MySQL entfernt. Überprüfen Sie daher den Link zu FOUND_ROWS, bevor Sie dies verwenden, wenn Sie bereits damit vertraut waren.
Anatak

28

Wie so oft ist diese Frage höllisch verwirrend. Die Leute kommen hierher und haben zwei verschiedene Aufgaben :

  1. Sie müssen wissen, wie viele Zeilen in der Tabelle enthalten sind
  2. Sie müssen wissen, ob eine Abfrage Zeilen zurückgegeben hat

Das sind zwei absolut unterschiedliche Aufgaben, die nichts gemeinsam haben und nicht mit derselben Funktion gelöst werden können. Ironischerweise muss für keinen von ihnen die eigentliche PDOStatement::rowCount()Funktion verwendet werden.

Mal sehen warum

Zeilen in der Tabelle zählen

Vor der Verwendung von PDO habe ich einfach verwendet mysql_num_rows().

Bedeutet, dass du es schon falsch gemacht hast. Das Verwenden mysql_num_rows()oder rowCount()Zählen der Anzahl der Zeilen in der Tabelle ist eine echte Katastrophe in Bezug auf den Verbrauch der Serverressourcen. Eine Datenbank muss alle Zeilen von der Festplatte lesen, den Speicher auf dem Datenbankserver belegen und dann all diesen Datenhaufen an PHP senden, wobei auch der Speicher des PHP-Prozesses verbraucht wird, wodurch Ihr Server absolut grundlos belastet wird.
Außerdem macht es einfach keinen Sinn, nur Zeilen auszuwählen, um sie zu zählen. count(*)Stattdessen muss eine Abfrage ausgeführt werden. Die Datenbank zählt die Datensätze aus dem Index heraus, ohne die tatsächlichen Zeilen zu lesen, und gibt dann nur eine Zeile zurück.

Zu diesem Zweck ist der in der akzeptierten Antwort vorgeschlagene Code fair.

Zählen der zurückgegebenen Zahlenzeilen.

Der zweite Anwendungsfall ist nicht so katastrophal wie sinnlos: Wenn Sie wissen müssen, ob Ihre Abfrage Daten zurückgegeben hat, haben Sie immer die Daten selbst!

Angenommen, Sie wählen nur eine Zeile aus. In Ordnung, Sie können die abgerufene Zeile als Flag verwenden:

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

Wenn Sie viele Zeilen benötigen, können Sie verwenden fetchAll().

fetchAll() ist etwas, das ich nicht will, da ich manchmal mit großen Datenmengen zu tun habe

Ja natürlich, für den ersten Anwendungsfall wäre es doppelt so schlimm. Aber wie wir bereits gelernt haben, nur nicht die Zeilen nur , sie zu zählen, weder mit rowCount()noch fetchAll().

Wenn Sie jedoch die ausgewählten Zeilen tatsächlich verwenden möchten, ist die Verwendung nicht falsch fetchAll(). Denken Sie daran, dass Sie in einer Webanwendung niemals eine große Anzahl von Zeilen auswählen sollten. Nur Zeilen , die tatsächlich auf einer Webseite verwendet werden sollen, ausgewählt werden daher sind Sie bei Verwendung bekommen LIMIT, WHEREoder eine ähnliche Klausel in der SQL. Und für eine so moderate Datenmenge ist es in Ordnung, sie zu verwenden fetchAll(). Und wieder verwenden Sie einfach das Ergebnis dieser Funktion in der Bedingung:

$stmt->execute();
$data = $stmt->fetchAll();
if (!$data) { // again, no rowCount() is needed!
    echo 'No data found';
}

Und natürlich ist es ein absoluter Wahnsinn , eine zusätzliche Abfrage auszuführen , um festzustellen, ob Ihre andere Abfrage Zeilen zurückgegeben hat, wie in den beiden oberen Antworten vorgeschlagen.

Zählen der Anzahl der Zeilen in einer großen Ergebnismenge

In einem so seltenen Fall, wenn Sie eine wirklich große Anzahl von Zeilen auswählen müssen (z. B. in einer Konsolenanwendung), müssen Sie eine ungepufferte Abfrage verwenden , um den verwendeten Speicher zu reduzieren. Dies ist jedoch der Fall, wenn rowCount() es nicht verfügbar ist , sodass diese Funktion ebenfalls nicht verwendet werden kann.

Daher ist dies der einzige Anwendungsfall, in dem Sie möglicherweise eine zusätzliche Abfrage ausführen müssen, falls Sie eine genaue Schätzung für die Anzahl der ausgewählten Zeilen benötigen.


Dies ist nützlich, wenn die API die Gesamtergebnisse einer Suchabfrage ausdrucken muss. Es gibt Ihnen nur 10 oder 15 Zeilen zurück, aber es sollte Ihnen auch sagen, dass es insgesamt 284 Ergebnisse gibt.
Andres SK

4
@andufo ist es nicht. Bitte denken Sie daran: Ein Entwickler sollte dies niemals so tun. Suchanfragen sollten niemals alle 284 Zeilen zurückgeben. 15 müssen zurückgegeben werden, um anzuzeigen, und eine Zeile aus einer separaten Abfrage, um zu bestätigen, dass 284 gefunden wurden.
Ihr gesunder Menschenverstand

2
Dies ist ein sehr guter Punkt - zunächst nicht intuitiv, aber gültig. Die meisten Leute vergessen, dass zwei einfache SQL-Abfragen viel schneller sind als eine etwas größere. Um eine Zählung zu rechtfertigen, müssten Sie eine sehr langsame Abfrage haben, die nicht optimiert werden kann und wahrscheinlich nur wenige Ergebnisse liefert. Vielen Dank für den Hinweis!
PeerBr

@Ihr gesunder Menschenverstand: Nur seien Sie sicher: Wird fetchAll () keine schlechte Idee sein, wenn die Ergebnismenge sehr groß ist? Wäre es nicht besser, fetch () zu verwenden, um Daten nacheinander abzurufen?
timmornYE

@timmornYE das ist genau das, was im letzten Absatz meiner Antwort gesagt wird
Ihr gesunder Menschenverstand

21

Das ist super spät, aber ich bin auf das Problem gestoßen und mache das:

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 ist wirklich einfach und leicht. :) :)


19
Die Auswahl aller Daten nur zum Zählen verstößt gegen die grundlegendsten Regeln der Datenbankinteraktion.
Ihr gesunder Menschenverstand

Möglicherweise möchten Sie einen Fortschrittsbalken für alle zurückgegebenen Werte haben, daher müssen Sie die Anzahl der Zeilen im Voraus kennen.
Jonny

18

Am Ende habe ich Folgendes verwendet:

$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>";
}

12

Dieser Beitrag ist alt, aber das Abrufen der Zeilenanzahl in PHP mit PDO ist einfach

$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();

3
Siehe die Dokumentation in der Antwort von karim79. Dies funktioniert manchmal, ist aber nicht zuverlässig.
Oktober

5

Dies ist ein alter Beitrag, der jedoch frustriert ist, nach Alternativen zu suchen. Es ist sehr bedauerlich, dass PDO diese Funktion nicht bietet, zumal PHP und MySQL in der Regel Hand in Hand gehen.

Es gibt einen unglücklichen Fehler bei der Verwendung von fetchColumn (), da Sie diese Ergebnismenge nicht mehr (effektiv) verwenden können, wenn fetchColumn () die Nadel in die nächste Zeile bewegt. Zum Beispiel, wenn Sie ein ähnliches Ergebnis wie haben

  1. Obst-> Banane
  2. Obst-> Apfel
  3. Obst-> Orange

Wenn Sie fetchColumn () verwenden, können Sie feststellen, dass 3 Früchte zurückgegeben werden. Wenn Sie jetzt das Ergebnis durchlaufen, haben Sie nur zwei Spalten. Der Preis von fetchColumn () ist der Verlust der ersten Spalte der Ergebnisse, die nur zu finden sind heraus, wie viele Zeilen zurückgegeben wurden. Dies führt zu einer schlampigen Codierung und bei der Implementierung zu völlig fehlerhaften Ergebnissen.

Mit fetchColumn () müssen Sie nun einen völlig neuen Aufruf und eine neue MySQL-Abfrage implementieren, um eine neue Arbeitsergebnismenge zu erhalten. (was sich hoffentlich seit Ihrer letzten Abfrage nicht geändert hat), ich weiß, unwahrscheinlich, aber es kann passieren. Auch der Aufwand für doppelte Abfragen bei der Validierung aller Zeilenzahlen. Was für dieses Beispiel klein ist, aber 2 Millionen Zeilen in einer verknüpften Abfrage analysiert, ist kein angenehmer Preis.

Ich liebe PHP und unterstütze alle, die an seiner Entwicklung beteiligt sind, sowie die gesamte Community, die täglich PHP verwendet, aber ich hoffe wirklich, dass dies in zukünftigen Versionen behoben wird. Dies ist "wirklich" meine einzige Beschwerde bei PHP PDO, was ansonsten eine großartige Klasse ist.


2

Beantworte dies, weil ich mich damit gefangen habe, weil ich das jetzt weiß und es vielleicht nützlich sein wird.

Denken Sie daran, dass Sie die Ergebnisse nicht zweimal abrufen können. Sie müssen das Abrufergebnis im Array speichern, die Zeilenanzahl von abrufen count($array)und die Ergebnisse mit ausgeben foreach. Beispielsweise:

$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
    }                       
}

1

Wenn Sie nur eine Anzahl von Zeilen (nicht die Daten) erhalten möchten, dh. Wenn Sie COUNT (*) in einer vorbereiteten Anweisung verwenden, müssen Sie nur das Ergebnis abrufen und den Wert lesen:

$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)

Das Abrufen aller Zeilen (Daten), um eine einfache Zählung durchzuführen, ist eine Verschwendung von Ressourcen. Wenn die Ergebnismenge groß ist, kann Ihr Server daran ersticken.



1

Um Variablen innerhalb einer Abfrage zu verwenden, müssen Sie bindValue()oder verwenden bindParam(). Und nicht verketten die Variablen mit" . $variable . "

$statement = "SELECT count(account_id) FROM account
                  WHERE email = ? AND is_email_confirmed;";
$preparedStatement = $this->postgreSqlHandler->prepare($statement);
$preparedStatement->bindValue(1, $account->getEmail());
$preparedStatement->execute();
$numberRows= $preparedStatement->fetchColumn();

GL


0

Wenn es um MySQL geht , wie viele Zeilen in einer Tabelle mit PHP PDO gezählt oder abgerufen werden sollen, verwende ich diese

// 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'];

Credits gehen an Mike @ codeofaninja.com


-1

Ein schneller Einzeiler, um den ersten Eintrag zurückzugeben. Dies ist gut für sehr einfache Fragen.

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

Referenz


-1

Ich habe es $count = $stmt->rowCount();mit Oracle 11.2 versucht und es hat nicht funktioniert. Ich habe mich für eine for-Schleife entschieden, wie unten gezeigt.

   $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

Für direkte Abfragen, bei denen ich eine bestimmte Zeile haben möchte und wissen möchte, ob sie gefunden wurde, verwende ich Folgendes:

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

Es gibt eine einfache Lösung. Wenn Sie PDO verwenden, stellen Sie wie folgt eine Verbindung zu Ihrer Datenbank her:

try {
    $handler = new PDO('mysql:host=localhost;dbname=name_of_your_db', 'your_login', 'your_password'); 
    $handler -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} 
    catch (PDOException $e) {   
    echo $e->getMessage();
}

Dann lautet die Abfrage an DB:

$query = $handler->query("SELECT id FROM your_table WHERE ...");

Und schließlich, um die Zeilen zu zählen, die Ihrer Abfrage entsprechen, schreiben Sie wie folgt

$amountOfRows = $query->rowcount();

Warum gibt mir das die meiste Zeit -1 zurück? Auch wenn es Daten gibt. .
Ingus

-1

fetchColumn ()

wird verwendet, wenn Sie die Anzahl der Datensätze erhalten möchten [effisien]

$sql   = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
$res   = $conn->query($sql);
$count = $res->fetchColumn(); // ex = 2

Abfrage()

wird verwendet, wenn Daten und Anzahl der Datensätze abgerufen werden sollen [Optionen]

$sql = "SELECT * FROM fruit WHERE calories > 100";
$res = $conn->query($sql);

if ( $res->rowCount() > 0) {

    foreach ( $res as $row ) {
        print "Name: {$row['NAME']} <br />";
    }

}
else {
    print "No rows matched the query.";
}

PDOStatement :: rowCount


Das solltest du niemals tun. Auf einem mehr oder weniger großen Tisch wird der gesamte Serverspeicher aufgebraucht und der Server zum Absturz gebracht
Your Common Sense

Jetzt dupliziert Ihre Antwort nur noch ein Dutzend vorhandene Antworten.
Ihr

-2

wenn Sie in Ihrer MySQL-Anweisung ein COUNT (*) wie in

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

Ihre MySQL-Abfrage zählt bereits die Anzahl der Ergebnisse. Warum in PHP erneut zählen? um das Ergebnis Ihrer MySQL zu erhalten

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

und $nbenthält die Ganzzahl, die Sie mit Ihrer MySQL-Anweisung gezählt haben, etwas lang zum Schreiben, aber schnell zum Ausführen

Bearbeiten: Entschuldigung für den falschen Beitrag, aber als Beispiel für eine Abfrage mit Zählung in schlug ich vor, das MySQL-Ergebnis zu verwenden. Wenn Sie die Zählung in SQL nicht verwenden, ist fetchAll () effizient, wenn Sie das Ergebnis in einer Variablen speichern Sie werden keine Linie verlieren.

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

count($table)gibt die Anzahl der Zeilen zurück und Sie können das Ergebnis nach like $row = $table[0] oder using a weiterhin verwendenforeach

foreach($table as $row){
  print $row->id;
}

1
Die Frage ist, wie man zählt, wenn man in seiner MySQL-Erklärung KEIN COUNT (*) macht
Your Common Sense

-2

Hier ist eine maßgeschneiderte Erweiterung der PDO-Klasse mit einer Hilfsfunktion zum Abrufen der Anzahl der Zeilen, die in den "WHERE" -Kriterien der letzten Abfrage enthalten sind.

Je nachdem, welche Befehle Sie verwenden, müssen Sie möglicherweise weitere 'Handler' hinzufügen. Derzeit funktioniert es nur für Abfragen, die "FROM" oder "UPDATE" verwenden.

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();
    }
}

Das Problem ist keine Mühe wert. Eine solche Nummer wird so selten benötigt, dass man keine dedizierte Nebenstelle benötigt. Ganz zu schweigen davon, dass vorbereitete Anweisungen nicht unterstützt werden - der einzige Grund, PDO zu verwenden.
Ihr gesunder Menschenverstand

-2

Sie können die beste Methode in einer Zeile oder Funktion kombinieren und die neue Abfrage automatisch für Sie generieren lassen:

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

$numRows = getRowCount($query);

Nichts am besten in dieser Methode. Es macht absolut keinen Sinn, eine zusätzliche Abfrage auszuführen, um nur zu wissen, wie viele Zeilen zurückgegeben wurden.
Ihr gesunder Menschenverstand

-2
<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>

1
Das ist eine wirklich schlechte Idee. Die Auswahl aller Zeilen ist eine enorme Verschwendung von Bandbreite.
Nafees

-2
function count_x($connect) {  
 $query = "  SELECT * FROM tbl WHERE id = '0' ";  
 $statement = $connect->prepare($query);  $statement->execute();  
 $total_rows = $statement->rowCount();  
 return $total_rows; 
}

-4

Parameter verwenden array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL), sonst -1 anzeigen:

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

Beispiel:

$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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.