Jochen: mysql count

Hi, wenn meine Abfrage

select a,b,c,d FROM tabelle where bedingung1 AND bedingung2 AND bedingung3

lautet, wie setze ich dann count ein, um im Ergebnis die Anzahl der gefundenen Datensätze zu erhalten? Bisher benutze ich immer 2 x hintereinander dieselbe Query und die Funktion mysql_num_rows nach der ersten.

VG, Jochen

  1. Hi, wenn meine Abfrage

    select a,b,c,d FROM tabelle where bedingung1 AND bedingung2 AND bedingung3
    

    lautet, wie setze ich dann count ein, um im Ergebnis die Anzahl der gefundenen Datensätze zu erhalten? Bisher benutze ich immer 2 x hintereinander dieselbe Query und die Funktion mysql_num_rows nach der ersten.

    Tschuldigung, wichtige Information vergessen:

    select a,b,c,d FROM tabelle where bedingung1 AND bedingung2 AND bedingung3 LIMIT 0, 50
    

    Da das aber die seitenweise Abfrage darstellt (50 Einträge je Seite) und ich weiß, dass die gesamtanzahl der Ergebnisse > 1000 ist, bezieht sich meine Frage darauf, in diese Abfrage auch die Frage nach der Gesamtanzahl des Ergebnisses einzubeziehen. Und das mache ich normal über 2 Abfragen, 1 x ohne LIMIT, einmal dann mit LIMIT.

    VG, Jochen

    1. Tach!

      select a,b,c,d FROM tabelle where bedingung1 AND bedingung2 AND bedingung3 LIMIT 0, 50
      

      Da das aber die seitenweise Abfrage darstellt (50 Einträge je Seite) und ich weiß, dass die gesamtanzahl der Ergebnisse > 1000 ist, bezieht sich meine Frage darauf, in diese Abfrage auch die Frage nach der Gesamtanzahl des Ergebnisses einzubeziehen. Und das mache ich normal über 2 Abfragen, 1 x ohne LIMIT, einmal dann mit LIMIT.

      Wenn du nur die Anzahl haben willst, frag das DBMS danach und las dir nicht alle Datensätze liefern, um sie selbst zu zählen (oder das von einer Funktion machen zu lassen).

      In deinem Fall mit dem LIMIT gibt es jedoch die Möglichkeit, das Wort SQL_CALC_FOUND_ROWS nach dem SELECT zu notieren und dann eine zweite Abfrage mit lediglich SELECT FOUND_ROWS() nachzuschieben.

      dedlfix.

      1. In deinem Fall mit dem LIMIT gibt es jedoch die Möglichkeit, das Wort SQL_CALC_FOUND_ROWS nach dem SELECT zu notieren und dann eine zweite Abfrage mit lediglich SELECT FOUND_ROWS() nachzuschieben.

        Kannte ich nicht, danke. Und das ist (viel?) schneller?

        VG, Jochen

        1. Tach!

          In deinem Fall mit dem LIMIT gibt es jedoch die Möglichkeit, das Wort SQL_CALC_FOUND_ROWS nach dem SELECT zu notieren und dann eine zweite Abfrage mit lediglich SELECT FOUND_ROWS() nachzuschieben.

          Kannte ich nicht, danke. Und das ist (viel?) schneller?

          Probier es. Es sind immer noch zwei Roundtrips zum Server, aber der hat den Wert, den FOUND_ROWS() liefert, bereits im Speicher. Andererseits könnte auch die COUNT()-Query bereits im Query-Cache sein, besonders wenn man sie mehrfach in recht kurzer Zeit ausführt.

          dedlfix.

          1. Probier es. Es sind immer noch zwei Roundtrips zum Server, aber der hat den Wert, den FOUND_ROWS() liefert, bereits im Speicher. Andererseits könnte auch die COUNT()-Query bereits im Query-Cache sein, besonders wenn man sie mehrfach in recht kurzer Zeit ausführt.

            Doch, Du hast recht. Es hat definitiv etwas gebracht. Danke.

            VG, Jochen

  2. Erster Hinweis: Das PHP Paket mysql ist deprecated, du solltest auf mysqli umstellen. Siehe www.php.net.

    Zweiter Hinweis, von hier

    Wenn Sie mysql_unbuffered_query() verwenden, liefert mysql_num_rows() solange nicht den korrekten Wert, bis Sie alle Zeilen der Ergebnismenge erhalten haben.

    Heißt: Wenn Du im buffered-Modus bist, saugt sich dein erster Select die komplette Treffermenge einmal vom Server ins PHP und schmeißt sie gleich danach wieder weg. Gut, dass Du nach einem besseren Weg suchst :)

    Wenn das deine Query ist

    select a,b,c,d FROM tabelle where bedingung1 AND bedingung2 AND bedingung3
    

    dann bestimmst Du so die Anzahl der Trefferzeilen und bleibst damit komplett im SQL Server.

    select count(*) FROM tabelle where bedingung1 AND bedingung2 AND bedingung3
    

    Du bekommst eine Row mit einer namenlosen Spalte zurück (die Du natürlich benennen kannst, wenn Du z.B. count(*) as Anzahl schreibst.

    Je nach Komplexität der Bedingungen und Tabellengröße strengt das den Server auch ein wenig an, aber eventuell kann er die Anzahl allein per Index-Scan bestimmen ohne die eigentlichen Tables zu lesen. Hängt von deinen Bedingungen und deinen Indexen ab. Musst Du ggf. beobachten; und wenn das zu lange dauert, musst Du Dir überlegen auf eine "Präzisionsaussage" bezüglich der Gesamtzahl zu verzichten, die Anzahl nur einmal zu bestimmen und dann in der User-Session festzuhalten.

    Rolf