Onkel Hans: Anzahl der Datensätze ausgeben

Hi,

ich bin _völliger_ Datenbankanfänger und scheitere gerade an folgendem Ziel: Ich möchte die Anzahl von bestimmten Datensätzen zählen und das Ergebnis dieser Zählung als Zahl ausgeben. Also nicht die Datensätze selbst, sondern nur deren Anzahl.

Für _alle_ Datensätze funktioniert es bei folgendem php-Quellcode:

<?php   include('db_connect.php');   $statement='SELECT `id` FROM `11_dbtest`';   $result=$db->query( $statement);   $number=$result->num_rows;   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$number." Datensätze in der Datenbank </p>\n"; ?>

Wenn ich jetzt nur bestimmte Datensätze zählen mlöhcte, in dem Fall alle, wo der Vorname "Hans" ist, habe ich es so versucht:

<?php   include('db_connect.php');   $statement='SELECT `vorname` FROM `11_dbtest` WHERE `vorname`=`Hans`';   $result=$db->query( $statement);   $number=$result->num_rows;   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$number." Datensätze in der Datenbank </p>\n"; ?>

Da kommt beim Aufruf der Seite aber die Notiz "Notice: Trying to get property of non-object in [...] on line [...]" und es kommt nicht zur Ausgabe einer ANzahl. Es steht lediglich "Insgesamt befinden sich Datensätze in der Datenbank." am Bildschirm.

Was am 2. Beispiel ist denn falsch? Wie muß ich das umschreiben, damit ich die Anzahl all jener Datensätze bekomme, wo "Hans" im Feld "vorname" eingetragen ist?

Danke für jede Hilfe!

Onkel Hans

  1. Hallo,

    Wenn ich jetzt nur bestimmte Datensätze zählen mlöhcte, in dem Fall alle, wo der Vorname "Hans" ist, habe ich es so versucht:

    dann versucht man - ganz besonders als Datenbankanfänger - die entsprechenden Statements in einem Client direkt auszuführen.

      $statement='SELECT vorname FROM 11\_dbtest WHERE vorname=Hans';

    Es gibt keine Spalte, die Hans heißt. Die (ekligen) Backticks verwendet MySQL zum Quoten von Bezeichnern, nicht von Zeichenketten.

    Zeichenketten werden in SQL üblicherweise in einfache Anführungszeichen gesetzt, d.h. Dein Statement sollte somit

        SELECT vorname FROM 11_dbtest WHERE vorname='Hans'

    lauten. Da Du nur an der Anzahl interessiert bist, ist es natürlich viel weniger Aufwand (für alle Beteiligten), genau die Anzahl abzufragen:

        SELECT         [COUNT](http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count)(`vorname`) Anzahl    -- ein netter Spaltenname (Alias)     FROM         `11_dbtest`     WHERE         `vorname` = 'Hans'

    Da Du in diesem Fall nur einen Datensatz erhältst, kannst Du direkt auf den Inhalt der Spalte mit dem Namen Anzahl zugreifen. PHPs num_row() liefert selbstverständlich *nicht* den von Dir gewünschten Wert. Es ist keine gute Idee, eine Million Datensätze abzurufen, wenn man nur an einer Zahl interessiert ist.

    Freundliche Grüße

    Vinzenz

    1. Hi,

      Dein Statement sollte somit
          SELECT vorname FROM 11_dbtest WHERE vorname='Hans'
      lauten.

      Nein, da der komplette Query ja mit ' begrenzt ist. Aber mit " funktioniert es:

      $statement='SELECT vorname FROM 11_dbtest WHERE vorname="Hans"';
      Bei _Deiner_ Lösung wäre nach ...WHERE vorname=' ja schon Ende.

      Da Du nur an der Anzahl interessiert bist, ist es natürlich viel weniger Aufwand (für alle Beteiligten), genau die Anzahl abzufragen:

          SELECT         [COUNT](http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count)(`vorname`) Anzahl    -- ein netter Spaltenname (Alias)     FROM         `11_dbtest`     WHERE         `vorname` = 'Hans'

      Und wieso ist das mit COUNT _weniger_ Aufwand?

      Da Du in diesem Fall nur einen Datensatz erhältst

      wie kommst Du da drauf?? Wenn es nur einen DS gäbe, bräucht ich mir ja kein Zählen antun. Natürlich gibt es mehrere Einträge mit Hans als Vornamen.

      Es ist keine gute Idee, eine Million Datensätze abzurufen, wenn man nur an einer Zahl interessiert ist.

      Aber wenn bei 1 Mio Datensätzen 635 mit "Hans" dabei sind, muß er ja auch Datensatz für datensatz abfragen und mitzählen. WIe gesagt, den Unterschied zwischen SELECT und SELECT COUNT verstehe ich nicht.

      Ich soll also _nicht_ diesen (funktionierenden) Code verwenden:

      <?php   include('db_connect.php');   $statement='SELECT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query( $statement);   $number=$result->num_rows;   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$number." Datensätze in der Datenbank.</p>\n"; ?>

      ????

      MfG

      Onkel Hans

      1. Yerf!

        Und wieso ist das mit COUNT _weniger_ Aufwand?

        Was ist wohl weniger Aufwand: wenn ich dir einen (schweren) Ordner mit 345 Blättern in die Hand geb und sag: "zähl selber" oder wenn ich dir einfach nur "345" mitteile?

        wie kommst Du da drauf??

        Die oben genannte "345" ist ein einzelner Datensatz. Du bekommst ja nur noch die Summe anstatt aller Datensätze (die du eh nicht brauchst).

        Aber wenn bei 1 Mio Datensätzen 635 mit "Hans" dabei sind, muß er ja auch Datensatz für datensatz abfragen und mitzählen. WIe gesagt, den Unterschied zwischen SELECT und SELECT COUNT verstehe ich nicht.

        Die Datenbank muss auf jeden Fall einmal durch, richtig. Aber wenn sie dann alle Datensätze zurückgibt ist das erstens eine wesentlich größere Datenmenge und zweitens muss PHP nochmals zählen.

        Gruß,

        Harlequin

        --
        RIP --- XHTML 2
        nur die Besten sterben jung

      2. Hallo,

        Dein Statement sollte somit
            SELECT vorname FROM 11_dbtest WHERE vorname='Hans'
        lauten.

        Nein, da der komplette Query ja mit ' begrenzt ist. Aber mit " funktioniert es:

        Lass doch einfach mal den Quatsch mit PHP weg. Du kannst ganz offensichtlich noch kein SQL. Du kannst ganz offensichtlich auch nicht besonders viel PHP. Aus diesem Grund rate ich Dir dringend dazu, SQL ohne Beimengung von PHP zu lernen. Setze im Client Deiner Wahl einfach SQL-Statements ab. Das kann auch gern phpMyAdmin sein. Angenehmer finde ich die MySQL-Workbench. Ab und an nutze ich einfach den Kommandozeilenclient.

        Und nein: es ist überhaupt keine gute Idee, doppelte Anführungszeichen zur Begrenzung von Zeichenketten in SQL zu verwenden. MySQL ist so ziemlich das einzige mir bekannte Datenbankmanagementsystem, dass diese in seinem (ziemlich bescheuerten) Standardmodus akzeptiert. Im strengeren Modus geht das auch in MySQL nicht.

        SQL-Standard ist das einfache Anführungszeichen. Geht überall. Deswegen ist es eine gute Idee, sich gleich anzugewöhnen, nur einfache Anführungszeichen zu verwenden. Umsteiger von MySQL auf irgendetwas anderes wie PostgreSQL, MS SQL Server, DB2, Oracle und Co. fallen unweigerlich auf die Nase, wenn sie sich nicht darüber im Klaren sind, was sie da machen.

        $statement='SELECT vorname FROM 11_dbtest WHERE vorname="Hans"';
        Bei _Deiner_ Lösung wäre nach ...WHERE vorname=' ja schon Ende.

        Nein. Ich nähme erstens doppelte Anführungszeichen, um mein SQL-Statement in eine PHP-Zeichenkette zu bekommen, nähme zweitens bei mysqli prepared-Statements und wüsste drittens, wie ich einfache Anführungszeichen innerhalb PHP-Zeichenketten, die von einfachen Anführungszeichen begrenzt sind, zu behandeln hätte.

        Nochmals:
        1. Schritt: Funktionierendes SQL-Statement im Client Deiner Wahl erstellen.

        Wenn Du diesen Schritt erfolgreich geschafft hast:

        1. Schritt: Dieses Statement über PHP ausführen und auf die Ergebnismenge zugreifen. Dabei nicht vergessen, den Fehlerfall mit einzukalkulieren, wie Dir dedlfix mit Engelsgeduld versucht hat beizubringen.

        Freundliche Grüße

        Vinzenz

  2. Hi!

    ich bin _völliger_ Datenbankanfänger und scheitere gerade an folgendem Ziel: Ich möchte die Anzahl von bestimmten Datensätzen zählen und das Ergebnis dieser Zählung als Zahl ausgeben. Also nicht die Datensätze selbst, sondern nur deren Anzahl.
      $statement='SELECT id FROM 11\_dbtest';
      $result=$db->query( $statement);
      $number=$result->num_rows;

    Dann nimm COUNT(*) ins SQL-Statement statt mysqli::num_rows. Damit num_rows funktionieren kann, müssen erst alle Datensätzt zum Client transportiert werden. Ein COUNT() liefert hingegen immer nur einen einzigen Wert.

      include('db_disconnect.php');

    Ein Disconnect ist nicht unbedingt erforderlich. Lediglich wenn das Script nach der Abfrage noch länger läuft und/oder der Speicherplatz freigegeben werden muss muss man sich die "Mühe" des Disconnect machen.

    Wenn ich jetzt nur bestimmte Datensätze zählen mlöhcte, in dem Fall alle, wo der Vorname "Hans" ist, habe ich es so versucht:
      $statement='SELECT vorname FROM 11\_dbtest WHERE vorname=Hans';

    Die Backticks sind Quotierzeichen für Identifizierer (Spaltennamen etc.) Strings werden mit '' oder "" eingefasst.

      $result=$db->query( $statement);
      $number=$result->num_rows;
    Da kommt beim Aufruf der Seite aber die Notiz "Notice: Trying to get property of non-object in [...] on line [...]" und es kommt nicht zur Ausgabe einer ANzahl.

    Dann steht wohl in $result etwas anderes als du erwartet hast. Prüf das mit var_dump(). Anschließend schau ins PHP-Handbuch, wann der angezeigte Wert zurückgegeben wird und erweitere dein Script um eine Fehlerbehandlung. Es ist nicht sinnvoll nur vom Gutfall auszugehen, Fehler gibt es nicht nur in Form von selbst fabrizierten Syntaxfehlern.

    Lo!

    1. Hi,

      OK, ich hab jetzt bei 3 Antworten gelesen, ich soll mit COUNT arbeiten. Kann dann bitte wer so nett sein und mir verraten, wie ich dann den Code formulieren soll? Ich komm nicht drauf. Ein

      <?php   include('db_connect.php');   $statement='COUNT SELECT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

      liefert mir ein leeres Ergebnis, da steht dann einfach "Insgesamt befinden sich Datensätze in der Datenbank." dort. Ohne Fehlermeldung.

      MfG

      Onkel Hans

      1. Hi!

        OK, ich hab jetzt bei 3 Antworten gelesen, ich soll mit COUNT arbeiten.

        Ja, denn mit COUNT() zählt das DBMS und liefert nur das Zählergebnis. Ohne COUNT() werden alle zutreffenden Datensätze geliefert und erst der Client (PHP) zählt.

        <?php   include('db_connect.php');   $statement='COUNT SELECT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

        liefert mir ein leeres Ergebnis, da steht dann einfach "Insgesamt befinden sich Datensätze in der Datenbank." dort. Ohne Fehlermeldung.

        Du hast immer noch kleine Fehlerbehandlung eingebaut, denn dann würdest du einen Systaxfehler zu sehen bekommen. PHP-Fehler werden mit einer PHP-Fehlermeldung angezeigt (wenn es nicht unterdrückt wurde). MySQL-Fehler hingegen werden nicht angezeigt, man muss die Rückgabewerte der verwendeten Funktionen auswerten, und wenn sie einen Fehler signalisieren, kann man sich den Wortlaut mit/aus den entsprechenden Funktionen/Eigenschaften abfragen. Beispiele für Fehlerbehandlungen finden sich im PHP-Handbuch. (Allerdings sollte man sich statt "or die(...)" eine für den Anwender geeignetere Methode des Daraufreagierens überlegen).

        Die Syntax für die Zählung der Datensätze lautet: SELECT COUNT(*) FROM ...

        Lo!

        1. Hi,

          Die Syntax für die Zählung der Datensätze lautet: SELECT COUNT(*) FROM ...

          OK, das habe ich geändert. Der Code lautet jetzt:

          <?php   include('db_connect.php');   $statement='SELECT COUNT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

          Jetzt kommt keine Fehlermeldung und kein Hinweis mehr, allerdings auch kein Ergebnis. Ich bekomme wieder das schon bekannte "Insgesamt befinden sich Datensätze in der Datenbank." zu lesen. (Im konkreten Fall würde ich aber momentan ein "Insgesamt befinden sich 2 Datensätze in der Datenbank." erwarten!)

          Was fehlt mir denn noch im Programmcode? Oder hab ich noch immer was falsch?

          MfG

          Onkel Hans

          1. Hello,

            OK, das habe ich geändert. Der Code lautet jetzt:

            <?php   include('db_connect.php');   $statement='SELECT COUNT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

            Jetzt kommt keine Fehlermeldung und kein Hinweis mehr, allerdings auch kein Ergebnis. Ich bekomme wieder das schon bekannte "Insgesamt befinden sich Datensätze in der Datenbank." zu lesen. (Im konkreten Fall würde ich aber momentan ein "Insgesamt befinden sich 2 Datensätze in der Datenbank." erwarten!)

            Was fehlt mir denn noch im Programmcode? Oder hab ich noch immer was falsch?

            Du musst den Datensatz noch aus dem Resultset herausholen.

            <?php    include('db_connect.php');    $statement='SELECT COUNT `vorname` `anzahl` FROM `11_dbtest` WHERE `vorname`="Hans"';    $result = $db->query($statement);    $_row   = $result->fetch_assoc();    include('db_disconnect.php');  ## was macht das genau?    echo"<p>Insgesamt befinden sich " . {$_row['anzahl']} . " Datensätze in der Datenbank.</p>\n"; ?>

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de

            1. Hi,
              hab vor deiner Antwort grad die von dedlfix gelesen und er schreibt dort:

              Ich schrieb: SELECT COUNT Klammer auf, Stern, Klamer zu FROM ... COUNT() ist eine Funktion. Ob man da * oder einen Spaltennamen angibt, kann das Ergebnis beeinflussen. Bei * werden alle Datensätze gezählt, bei einem Spaltennamen nur die Datensätze, die keinen NULL-Wert in der Spalte haben. Auf alle Fälle braucht es da aber die Klammern.

              Laut dedlfix MUSS man ja Klammern verwenden (wenn ich ihn richtig verstanden habe). Das steht irgendwie im Gegensatz zu deiner Antwort. Jetzt bin ich _noch mehr_ verwirrt. :-(

              <?php
                 include('db_connect.php');
                 $statement='SELECT COUNT vorname anzahl FROM 11\_dbtest WHERE vorname="Hans"';
                 $result = $db->query($statement);
                 $_row   = $result->fetch_assoc();

                 include('db_disconnect.php');  ## was macht das genau?

                 echo"<p>Insgesamt befinden sich " . {$_row['anzahl']} . " Datensätze in der Datenbank.</p>\n";

              ?>
              [/code

              ??? *kopfkratz*

              MfG

              Onkel Hans

              PS: Das include('db_disconnect.php'); beendet die DB-Verbindung mit close().

              1. Hello,

                Laut dedlfix MUSS man ja Klammern verwenden (wenn ich ihn richtig verstanden habe). Das steht irgendwie im Gegensatz zu deiner Antwort. Jetzt bin ich _noch mehr_ verwirrt. :-(

                Das tut mir ja nun leid, dass ich die Klammern unterschlagen habe. Soll nicht wieder vorkommen :-)

                Ich habe allerdings auch angenommen, dass Du dem Link von Vinzenz schon mal gefolgt warst, und etwas gelesen hast. Wie wäre es mit etwas Nachlesen?
                http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count

                Liebe Grüße aus dem schönen Oberharz

                Tom vom Berg

                --
                 ☻_
                /▌
                / \ Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de

                1. Ich habe allerdings auch angenommen, dass Du dem Link von Vinzenz schon mal gefolgt warst, und etwas gelesen hast. Wie wäre es mit etwas Nachlesen?
                  http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count

                  Auf dieser ...-Seite war ich heute schon 4 mal und komme nicht weiter. Wie ich gerade dedlfix geschrieben habe:

                  Ist es denn gegen das SELFHTML-Prinzip, dass man die Lösung an Hand eines gültigen/funktionierenden Codes erklärt? Ich bin nun halt mal kein Informatiker und Links zu irgendwelchen Werken helfen mir nicht weiter. :-(

                  Onkel Hans, der sich jetzt langsam von Antwort zu Antwort immer weniger auskennt. :-(

                  1. Hello,

                    Ich habe allerdings auch angenommen, dass Du dem Link von Vinzenz schon mal gefolgt warst, und etwas gelesen hast. Wie wäre es mit etwas Nachlesen?
                    http://dev.mysql.com/doc/refman/5.1/en/group-by-functions.html#function_count

                    Auf dieser ...-Seite war ich heute schon 4 mal und komme nicht weiter. Wie ich gerade dedlfix geschrieben habe:

                    Ist es denn gegen das SELFHTML-Prinzip, dass man die Lösung an Hand eines gültigen/funktionierenden Codes erklärt? Ich bin nun halt mal kein Informatiker und Links zu irgendwelchen Werken helfen mir nicht weiter. :-(

                    Es wird schon werden :-)

                    Nun bau doch noch die Erkenntnis, dass man count(*) schreiben sollte für ganz allgmeine Anzahl-Abfrage und dass Du das Ergebnis noch abhollen solltest aus dem Resultset
                    ?t=203753&m=1378480

                    <?php
                       include('db_connect.php');
                       $statement='SELECT COUNT(*) anzahl FROM 11\_dbtest WHERE vorname="Hans"';
                       $result = $db->query($statement);
                       $_row   = $result->fetch_assoc();

                       include('db_disconnect.php');  ## was macht das genau?

                       echo "<p>Insgesamt befinden sich {$_row['anzahl']} Datensätze in der Datenbank.</p>\n";
                    ?>

                    Ich habe es jetzt nicht selber ausprobiert, aber mMn müsste das jetzt funktionieren.

                    Liebe Grüße aus dem schönen Oberharz

                    Tom vom Berg

                    --
                     ☻_
                    /▌
                    / \ Nur selber lernen macht schlau
                    http://bergpost.annerschbarrich.de

                    1. Danke, Tom, schön wärs, nur leider liefert mir

                      <?php    $statement='SELECT COUNT (*) `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   $row=$result->fetch_assoc();   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$row." Datensätze in der Datenbank.</p>\n"; ?>

                      ein: Fatal error: Call to a member function fetch_assoc() on a non-object in xxx.php on line 24.

                      :-/

                      Die 24er line ist die bei mir, wo das $row=$result->fetch_assoc(); steht.

                      MfG

                      Onkel Hans

                      1. Hello,

                        was steht in db_connect.php ?
                        Was steht in db_disconnect.php?

                        Außerdem ist es nicht der Code, den ich Dir gepostet hatte.

                        Schau Dir ausßerdem mal ein Beipiel an:

                        http://de2.php.net/manual/en/mysqli-result.fetch-assoc.php

                        Liebe Grüße aus dem schönen Oberharz

                        Tom vom Berg

                        --
                         ☻_
                        /▌
                        / \ Nur selber lernen macht schlau
                        http://bergpost.annerschbarrich.de

                        1. Hi,

                          was steht in db_connect.php ?
                          Was steht in db_disconnect.php?

                          das ist die Verbindung zur DB sowie die Trennung dieser Verbindung. In der 'db_connect.php' steht:

                          <?php   $db=@new mysqli('Hostname','Benutzername','Benutzerkennwort','Datenbankname');   $db->set_charset('utf8');   if (mysqli_connect_errno())     {        die("<h1>Datenbank Verbindungsfehler</h1><p>Bitte entschuldigen Sie, es kann momentan keine Verbindung zur Datenbank aufgebaut werden</p><p>".mysqli_connect_error()."(".mysqli_connect_errno().")</p><p>Wenn dieses Problem weiterhin besteht, melden Sie das bitte per Mail an <a href=\"mailto:admin@example.net\">admin@example.net</a>.</p>");     } ?>

                          In der 'db_disconnect.php' steht:

                          <?php   $db->close(); ?>

                          Außerdem ist es nicht der Code, den ich Dir gepostet hatte.

                          Stimmt, da hatte ich etwas übersehen.

                          <?php
                          include('db_connect.php');
                          $statement='SELECT COUNT(*) anzahl FROM 11\_dbtest WHERE vorname="Hans"';
                          $result = $db->query($statement);
                          $_row   = $result->fetch_assoc();
                          include('db_disconnect.php');
                          echo "<p>Insgesamt befinden sich {$_row['anzahl']} Datensätze in der Datenbank.</p>\n";
                          ?>

                          Verstehe ich das richtig, Du gibst diesem Zählvorgang einen Namen? In dem Fall heißt der Zählvorgang also "anzahl"? Das verwirrt mich insofern, als ich auf sämtlichen themenspezifischen Seiten, die ich bisher vor mir hatte, dies nicht vorkommt. Siehe zB. das Kapitel "Zeilen zählen" im SQL Handbuch.
                          Wenn ich den von Dir vorgeschlagenen Code verwende, 1:1 kopiert, funktioniert es, die richtige Anzahl der betroffenen Datensätze wird ausgegeben. Nur - wie schon gesagt - ich finde nirgendwo eine Erklärung zu der Sache mit der Namensgebung für die Zählung.

                          Im PHP Handbuch habe ich beim Herumsuchen zufällig das Kapitel "mysqli rollback" (Was immer das auch ist) gefunden und dort ist mir bei den Beispielen Folgendes ins Auge gefallen:

                          /* Rollback */ $mysqli->rollback(); if ($result = $mysqli->query("SELECT COUNT(*) FROM myCity"))  {    $row = $result->fetch_row();    printf("%d rows in table myCity (after rollback).\n", $row[0]);    /* Free result */    $result->close();  }

                          Das hat mir den Denkanstoß gegeben, meinen Code umzuschreiben und weiter zu vereinfachen. Ich habe jetzt, um mein Ziel zu erreichen, folgenden Code:

                          <?php    include('db_connect.php');    $result=$db->query("SELECT COUNT(*) FROM `11_dbtest` WHERE `vorname`='Hans'");    $row = $result->fetch_row();    include('db_disconnect.php');    echo "<p>Insgesamt befinden sich $row[0] Datensätze in der Datenbank.</p>\n"; ?>

                          Das funktioniert wunderbar. Nachdem ich aber auch lernen und verstehen möchte, was ich hier tue, bitte ich trotzdem um ein paar Erklärungen. Wieso hat in Deinem Beispiel die Zählung einen Namen, während das in meiner aktuellen Lösung nicht der Fall ist? Du arbeitest mit "$_row= $result->fetch_assoc()" während bei mir jetzt ein "$row=$result->fetch_row()" verwendet wird. Was ist da der Unterschied? Gibt es da Vorteile/Nachteile? Und natürlich: Ist meine aktuelle Lösung so OK?

                          Was ich jetzt verstanden habe ist das Prinzip, dass der Server so oder so alle Datensätze durchgehen muß, um zu einem Zählergebnis zu kommen, dass es aber einfacher ist, wenn er diese Zahl dem Client schickt, statt alle gefundenen Datensätze, damit diese vom Client ein 2. mal gezählt werden müssen. Und genau dafür gibt es COUNT. Richtig??

                          Nicht richtig klar ist mir hingegen der Hinweis von dedlfix.

                          COUNT() ist eine Funktion. Ob man da * oder einen Spaltennamen angibt, kann das Ergebnis beeinflussen. Bei * werden alle Datensätze gezählt, bei einem Spaltennamen nur die Datensätze, die keinen NULL-Wert in der Spalte haben. Auf alle Fälle braucht es da aber die Klammern.

                          Ich finde leider nirgendwo eine Seite, wo das erklärt wird. Ich finde bei allen Beispielen eigentlich immer nur einen Code mit einem COUNT(*).

                          Naja, zumindest bin ich einen kleinen Schritt weiter dank Eurer Hilfe.

                          MfG

                          Onkel Hans

                          1. Hello,

                            was steht in db_connect.php ?
                            Was steht in db_disconnect.php?

                            das ist die Verbindung zur DB sowie die Trennung dieser Verbindung. In der 'db_connect.php' steht:

                            Das konnte ich mir schon dneken, aber leider nicht, ob ein Objekt erzeugt wird, oder ob klassisch mit prozeduraler Programmmierung gearbeitet wurde.

                            <?php   $db=@new mysqli('Hostname','Benutzername','Benutzerkennwort','Datenbankname');   $db->set_charset('utf8');   if (mysqli_connect_errno())     {        die("<h1>Datenbank Verbindungsfehler</h1><p>Bitte entschuldigen Sie, es kann momentan keine Verbindung zur Datenbank aufgebaut werden</p><p>".mysqli_connect_error()."(".mysqli_connect_errno().")</p><p>Wenn dieses Problem weiterhin besteht, melden Sie das bitte per Mail an <a href=\"mailto:admin@example.net\">admin@example.net</a>.</p>");     } ?>

                            In der 'db_disconnect.php' steht:

                            <?php   $db->close(); ?>

                            Außerdem ist es nicht der Code, den ich Dir gepostet hatte.

                            Stimmt, da hatte ich etwas übersehen.

                            <?php
                            include('db_connect.php');
                            $statement='SELECT COUNT(*) anzahl FROM 11\_dbtest WHERE vorname="Hans"';
                            $result = $db->query($statement);
                            $_row   = $result->fetch_assoc();
                            include('db_disconnect.php');
                            echo "<p>Insgesamt befinden sich {$_row['anzahl']} Datensätze in der Datenbank.</p>\n";
                            ?>

                            Verstehe ich das richtig, Du gibst diesem Zählvorgang einen Namen?

                            Nicht dem Vorgang, sondern dem Ergebnis.

                            In dem Fall heißt der Zählvorgang also "anzahl"? Das verwirrt mich insofern, als ich auf sämtlichen themenspezifischen Seiten, die ich bisher vor mir hatte, dies nicht vorkommt. Siehe zB. das Kapitel "Zeilen zählen" im SQL Handbuch.

                            Das führt dazu, dass PHP dann später ein assoziatives Array abfragen kann aus dem Resultset. Wenn man die Möglichkeit hat, mit Namen zu arbeiten anstelle von nichtssagenden Nummern (hier Index [0]), dann tue ich das auch. In einer Interpretersprache kostet das auch (fast) nichts.

                            Wenn ich den von Dir vorgeschlagenen Code verwende, 1:1 kopiert, funktioniert es, die richtige Anzahl der betroffenen Datensätze wird ausgegeben. Nur - wie schon gesagt - ich finde nirgendwo eine Erklärung zu der Sache mit der Namensgebung für die Zählung.

                            Da müsstest Du Dir mal ein gutes Buch zu MySQL besorgen, in dem das auch Schritt für Schritt erklärt wird. Im MySQL-Handbuch steht auch schon sehr viel, aber leider nicht alles.

                            [...]

                            Das hat mir den Denkanstoß gegeben, meinen Code umzuschreiben und weiter zu vereinfachen. Ich habe jetzt, um mein Ziel zu erreichen, folgenden Code:

                            ~~~ php <?php
                               include('db_connect.php');
                               $result=$db->query("SELECT COUNT(*) FROM 11_dbtest WHERE vorname='Hans'");
                               $row = $result->fetch_row();

                                 echo "<p>Insgesamt befinden sich $row[0] Datensätze in der Datenbank.</p>\n";
                                 include('db_disconnect.php');

                            ?>

                            ~~~

                            Hier besorgt sich PHP nur ein indiziertes Array, also eines, das keine Namen für seine Elemente benutzt. Das finde ich deshalb nicht gut, weil ich dann in der SQL-Abfrage die Reihenfolge der Ergebniselemente festlegen muss. Hier haben wir zwar nur einen Wert, den wir erwarten, aber wenn sich mal etwas ändert, und wir mehrere Werte zurückgeben müssen, dann muss ich die Änderungen durch mehrere Schichten hindurch beachten. Das ist verspielte Entschichtung.

                            SQL-Abfragen gehören in die eine Schicht, Auswertung der Abfragen in die nächste und die Aufbereitung der Anzeige in noch eine andere. Und die Übergabe an der "Schnittstelle" oder ich sage lieber "Verbindungsstelle" erfolgt hier per Namen. Das Gegenteil davon wäre dann ein Positionsparameter. Der müsste dann erstens immer an der richtigen Position übergeben werden und zweitens auch immer angegeben werden, auch wenn dafür kein Wert vorliegt.

                            Die Übergabe per Namen ist dann ein "Optionsparameter", denn der muss nur genannt werden, wenn ein Wert für ihn vorhanden ist.

                            Wenn Du diese Trennung beachtest, kannst Du deine Programme später viel leichter ändern und pflegen und auch leichter Module unterschiedliecher Entwickler (die das auch beachten) zusammenstöpseln zu einen Gesamtkunstwerk.

                            Liebe Grüße aus dem schönen Oberharz

                            Tom vom Berg

                            --
                             ☻_
                            /▌
                            / \ Nur selber lernen macht schlau
                            http://bergpost.annerschbarrich.de

                            1. Hi,

                              verstehe ich das richtig?

                              Mit SELECT COUNT(*) FROM tabelle WHERE wert='foo' werden serverseitig alle betroffenen Datensätze gezählt. Es entsteht ein namenloser Wert. Mit $row=$result->fetch_row() wird diese Zahl (dieses Zählergebnis) abgeholt und steht dann als erster Wert im indizierten Array '$row' zur Verfügung.

                              Mit SELECT COUNT(*) anzahl FROM tabelle WHERE wert='foo' bekommt das Ergebnis der Zählung den Namen 'Anzahl'. Mit $row=$result->fetch_assoc() wird dieses Ergebnis abgeholt und steht dann mit dem Index-namen 'anzahl' im assoziativen Array '$row' zur Verfügung.

                              Das heißt, sowohl fetch_row(), als auch fetch_assoc() holen einen Wert, das Ergebnis einer Zählung, vom Server ab und speichern diesen in einem Array. Der Unterschied ist nur, dass fetch_row() ein indiziertes Array produziert, während fetch_assoc() zu einem assozierten Array führt, wobei der Indes-Name im Query vorbestimmt wird.

                              Habe ich das richtig verstanden?

                              MfG

                              Onkel Hans

                                1. Hi, zunächst mal Danke für die Hilfe zur Lösung meines Basis-Problems.

                                  Das hast Du richtig verstanden. Außerdem kannst Du das ja auch nachlesen im PHP-Handbuch

                                  Tja, wenn das so einfach wäre. Ich kann solche Seiten lesen, solange ich will ... ich kann einfach mit der Didaktik nichts anfangen und bin danach genau so schlau wie vorher. Darum habe ich direkt nachgefragt, ob ich es richtig verstanden habe.

                                  So, nun möchte ich etwas Komplexeres versuchen - und natürlich scheritere ich seit Stunden daran. =(

                                  Folgendes möchte ich realisieren: In einem Formular kann ein Suchbegriff eingegeben werden. Außerdem kann ausgesucht werden, ob bei den Vornamen, bei den Familiennamen oder beim Geburtsjahr gesucht werden soll. Im Anschluß soll ausgegeben werden, auf wie viele Datensätze die Suchanfrage zutrifft. (Ich bin noch immer nicht bei der Ausgabe der Datensätze selbst, ich möchte nur das Zählergebnis wissen!)

                                  Da ich bösartige Angriffe abweisen möchte, soll der Code mit prepared Statements arbeiten. (Ich arbeite mit MySQLi.) Nachdem ich jetzt seit 4 1/2 Stunden alle mir einfallenden Variationen durch habe und mir auch kein var_dump oder Manuel mehr weiterhilft, wende ich mich wieder an Euch. =(

                                  Also das ist mein momentaner Versuch, funktioniert natürlich nicht.

                                  <?php   switch($_POST['suchort'])     {       case"Familienname":         $spalte="familienname";         break;       case"Vorname":         $spalte="vorname";         break;       case"Geburtsjahr":         $spalte="geburtsjahr";     }   include('db_connect.php');   $sql="SELECT COUNT(*) `zaehlergebnis` FROM `11_dbtest` WHERE `$spalte` = ? ";   $zaehlung=$db->prepare($sql);   $zaehlung->bind_param('s',$_POST['terminus']);   $zaehlung->execute();   $row=$zaehlung->fetch_assoc();   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich".$row[zaehlergebnis]."Datensätze in der Datenbank.</p>\n"; ?>

                                  Das liefert ein "Fatal error: Call to undefined method mysqli_stmt::fetch_assoc() in /kunden/151444_1040/webseiten/web02/testlabor/016/countinputresult2.php on line 35" - die Zeile 35 ist das "$row=$zaehlung->fetch_assoc();"

                                  Heißt das, wenn ich mit prepared Statements arbeite, muß ich die Zählung bestimmter Datensätze wieder _ganz_ anders angehen? =( Es gibt doch dieses bind result - muß das bei der Verwendung von prepared statements zur Anwendung kommen?

                                  Ich bitte um weitere Hilfe!

                                  MfG

                                  Onkel Hans

                              1. Hi!

                                Habe ich das richtig verstanden?

                                Du könntest das selbst überprüfen, wenn du die jeweiligen Beschreibungen im Handbuch läsest und mit var_dump() anschautest, was diese Funktionen liefern. Das geht entweder so:

                                  var_dump($result->fetch_row());

                                oder auf $row:

                                  $row = $result->fetch_row();
                                  var_dump($row);

                                Lo!

                          2. Hallo,

                            Das hat mir den Denkanstoß gegeben, meinen Code umzuschreiben und weiter zu vereinfachen. Ich habe jetzt, um mein Ziel zu erreichen, folgenden Code:

                            und bist durch eigenen Lerneffekt ungefähr dort angekommen, wo ich Dich hinleiten wollte.

                            <?php    $result=$db->query("SELECT COUNT(*) FROM `11_dbtest` WHERE `vorname`='Hans'");    $row = $result->fetch_row(); ?>

                            Das funktioniert wunderbar. Nachdem ich aber auch lernen und verstehen möchte, was ich hier tue, bitte ich trotzdem um ein paar Erklärungen. Wieso hat in Deinem Beispiel die Zählung einen Namen, während das in meiner aktuellen Lösung nicht der Fall ist?

                            Das liegt daran, dass Tom gemäß meinem Vorbild einen Aliasnamen verwendet hat. Die Verwendung von Aliasnamen ist bei berechneten Spalten meistens sinnvoll.

                            ~~~ sql » » »     SELECT

                                    COUNT(vorname) Anzahl    -- ein netter Spaltenname (Alias)
                                FROM
                                    11_dbtest
                                WHERE
                                    vorname = 'Hans'

                            ~~~

                            Die Auswirkung von Aliasnamen sieht man am besten, wenn man *kein* PHP verwendet, sondern einen handelsüblichen SQL-Client wie zum Beispiel die von mir bereits verlinkte MySQL-Workbench oder auch phpMyAdmin.

                            Freundliche Grüße

                            Vinzenz

          2. Hi!

            Die Syntax für die Zählung der Datensätze lautet: SELECT COUNT(*) FROM ...

            OK, das habe ich geändert. Der Code lautet jetzt:
              $statement='SELECT COUNT vorname FROM 11\_dbtest WHERE vorname="Hans"';

            Ich schrieb: SELECT COUNT Klammer auf, Stern, Klamer zu FROM ...
            COUNT() ist eine Funktion. Ob man da * oder einen Spaltennamen angibt, kann das Ergebnis beeinflussen. Bei * werden alle Datensätze gezählt, bei einem Spaltennamen nur die Datensätze, die keinen NULL-Wert in der Spalte haben. Auf alle Fälle braucht es da aber die Klammern.

            <?php   include('db_connect.php');   $statement='SELECT COUNT `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

            Jetzt kommt keine Fehlermeldung und kein Hinweis mehr, allerdings auch kein Ergebnis.

            Ja, und was steht in $result drin? Lass dir den Inhalt mit var_dump() anzeigen. Du siehst dann nämlich ein false, was wieder auf einen Fehler hindeutet. In der anschließenden Ausgabe siehst du nichts, weil das false im String-Kontext zu einem Leerstring wird. In $result ist aber auch im Gutfall noch nicht dein Zählergebnis drin, sondern ein mysqli_result-Objekt, das erst noch per Fetch nach dem einen enthaltenen Datensatz befragt werden muss.

            Was fehlt mir denn noch im Programmcode? Oder hab ich noch immer was falsch?

            Eine Fehlerbehandlung! Und die Lektüre von Grundlagenliteratur.

            Im PHP-Handbuch findest du unter der Beschreibung des Konstruktors von mysqli ein Beispiel zum Abfangen von Fehlern beim Verbindungsaufbau. Bei mysqli::query() findet sich wenigstens angedeutet eine Reaktion auf Fehler bei dessen Ausführung. Unter mysqli_result::fetch_assoc() und den anderen Fetch-Funktionen wird gezeigt, wie man Ergebnisse abholt - ebenfalls mit angedeuteter Fehlerbehandlung. Angedeutet ist sie deshalb, weil kein else-Zweig für den Fehlerfall zu sehen ist. Man sieht aber, dass das Ergebnis nur im Gutfall weiterverarbeitet wird. Und mysqli::error zeigt, wie man sich die Fehlermeldungen vom MySQL-Server abholt. Da ist allerdings die Logik bei mysqli::query() negiert, weil man da nur die Fehlermeldung zeigen will und keine vollständige Datenabfrage.

            Lo!

            1. Hi,

              so jetzt schaut es so aus:

              <?php   include('db_connect.php');   $statement='SELECT COUNT (*) `vorname` FROM `11_dbtest` WHERE `vorname`="Hans"';   $result=$db->query($statement);   include('db_disconnect.php');   echo"<p>Insgesamt befinden sich ".$result." Datensätze in der Datenbank.</p>\n"; ?>

              Selbes Ergebnis: Keine Fehlermeldung, und keine AUsgabe eines Ergebnisses. Deinen Ratschlag mit var_dump($result); habe ich befolgt, da kommt ein false raus. OK, und was mach ich jetzt?

              Wäre es nicht einfacher, den Code so hinzuschreiben, wie er richtig wäre und ihn anhand desselben zu erklären, als immer um 4 Ecken zu reden, was für Nichtinformatiker wie gar keine Hilfe gleich kommt?

              Onkel Hans

              1. Hi!

                Keine Fehlermeldung, und keine AUsgabe eines Ergebnisses. Deinen Ratschlag mit var_dump($result); habe ich befolgt, da kommt ein false raus. OK, und was mach ich jetzt?

                Du lässt dir nun vom DBMS anzeigen, was der konkrete Wortlaut der Meldung ist. DBMS-Fehlermeldungen werden nicht wie PHP-Meldungen auf dem Silbertablett serviert, sondern müssen abgeholt werden. Auf die entsprechende Handbuchseite verwies ich bereits. Dieses Fehlermeldungstext-Holen und -Ansehen brauchst du immer wieder, also mach das jetzt mal.

                Wäre es nicht einfacher, den Code so hinzuschreiben, wie er richtig wäre und ihn anhand desselben zu erklären, als immer um 4 Ecken zu reden, was für Nichtinformatiker wie gar keine Hilfe gleich kommt?

                Es gibt nicht nur ein "richtig". Als Programmierer, egal ob man nebenher noch Informatiker ist oder nicht, muss man auch anderen Code lesen und ihn für seine Zwecke umschreiben können. Ich verwies auf die Handbuchseiten, ich sprach mehrmals Fehlerbehandlung an - für mich wäre es auch einfacher, wenn du das zur Kenntnis nähmest und nicht immer anscheinend ignoriertest. Ich erwarte nicht, dass du auf Anhieb alles richtig machst, aber ich erwarte, dass du Hinweise sorgsam zur Kenntnis nimmst und konkret nachfragst, wenn du sie nicht verstehst.

                Lo!

  3. Was am 2. Beispiel ist denn falsch? Wie muß ich das umschreiben, damit ich die Anzahl all jener Datensätze bekomme, wo "Hans" im Feld "vorname" eingetragen ist?

    Du hast Backtickitis - Wenn du Hans notierst, strebt das DMBS idR. einen vergleich mit dem Feld "Hans" an, wenn du hingegen 'Hans' notierst, dann mit dem Wert Hans.

    Warum arbeitest du überhaupt mti num_rows? Idr. ist ein simples COUNT() vom DMBS wesentlich schneller abgearbeitet als eine komplette Datensammlung zurückzuliefern.