martin88: Aufteilung mehrere Seiten

Hi,
ich habe eine relativ komplizierte Query die ich im PHP aufbaue (sprich eine suche und je mehr einschränkungen gegeben werden des du komplexer wird sie natürlich).

Die Ergebnisse dieser suche möchte ich nun auf mehrere Seiten aufteilen.
Eingeschränkt wird dies, indem ich die nummer der aktuellen Seite über GET hole, die Anzahl der Einträge berücksichtige und den offset, sprich select ........... LIMIT start, offset.

Das klappt alles, nur brauch ich nun von dieser query die anzahl aller ergebnisse (count) damit ich sagen kann gehe zu seite 2,3,4... bzw die seiten die es überhaupt gibt anzeigen kann. Sprich wenn mir count 30 Datensätze liefert und ich hab 10 einträge pro seite wären dann natürlich 3 Seiten da.

Ich sehe leider im Moment keine andere Möglichkeit die query 2 mal auszuführen, am anfang wo ich alles selektiere + LIMIT.

Und dann nochmal mit COUNT damit ich die gesamten datensätze erhalte.

Ich weiß nicht ob es eine andere Möglichkeit gibt, die ganze query in sich selbst nochmal als subquery einzubauen als select ergibt noch weniger sinn.

Jemand noch eine Idee oder ist das einfach so?

lg

  1. Hi!

    Ich sehe leider im Moment keine andere Möglichkeit die query 2 mal auszuführen, am anfang wo ich alles selektiere + LIMIT.
    Und dann nochmal mit COUNT damit ich die gesamten datensätze erhalte.

    SQL_CALC_FOUND_ROWS ist dein Stichwort.

    Lo!

    1. Danke für die rasche antwort ich werds mir gleich ansehen!
      Vielen dank!

    2. Hi,
      super das hat wunderbar geklappt vielen dank.
      Jetzt hab ich noch ein Problem. Die $_POSTS für die such query muss ich mir ja irgendwie merken wenn ich jetzt zb. auf seite 2 gehe oder seite 3 und wieder zurück. Gibts da noch nen trick?

      Wenn ich normale ergebnisse anzeige hab ich ja das problem nicht da ich einfach select * mach, in dem fall muss ich mir aber die einschränkungen irgendwie merken,
      wäre für nen hilfreichen tipp dankbar,

      lg!

      1. Hi martin88,

        eine Variante wäre die Verwende von Hidden-Feldern, in denen kannst du die Sucheinschränkung speichern (die Sucheinschränkung, bitte nicht das MySQL Query!). Beim Link-Klick musst natürlich dafür sorgen, dass das Formular mit den Hiddenfeldern auch mitgeschickt wird. Das sollte i.d.R. unproblematisch sein, da du ein Get und Post Request "gleichzeitig" senden kannst, bzw. du kannst der "POST" URI einfach ein Query dranhängen, diese kann dann serverseitig auch als GET ausgewertet werden + die Post Variablen (Formular -> Hiddenfelder) sind ebenfalls auswertbar. Das ganze könntest du über Javascript realisierien. Also beim Linkaufruf wird eine Javascript Funktion mit Parameter ausgeführt, diese hängt an die URI ein Query bspw. "?site=2" dran, anschließend führst du über Javascript ein submit() aus.

        Du kannst natürlich auch die Sucheinschränkung im Get Query in der URI dran hängen, schaut aber unschön aus, zudem hast du das generelle Problem, dass die URI nur eine bestimmte Anzahl an Zeichen zulässt.

        Du könntest das ganze per Cookies oder SessionID realisieren, würde ich aber von abraten.

        Evtl. gibt es auch elegantere Varianten.

        Gruß Metalgurke

        1. Liebe Metalgurke,

          Evtl. gibt es auch elegantere Varianten.

          nimm doch eine Session!

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Liebe Metalgurke,

            Evtl. gibt es auch elegantere Varianten.

            nimm doch eine Session!

            Finde ich irgendwie nicht so dolle, warum extra ein Sessionhandling nur für eine benutzerdefinierte Suchanfrage (wahrscheinlich sogar noch mit einer Speicherung in einer DB)? An der Frage scheiden sich wahrscheinlich die Geister. Für mein dafürhalten, ist die Variante über eine Session zu aufwendig.

            @Felix Riesterer
            Wie genau könnte denn deine Session-Lösung aussehen?
            Würde mich mal interessieren, vielleicht ist sie ja wirklich besser und ich habe direkt noch etwas dazu gelernt.

            Gruß Metalgurke

            1. Hi!

              Für mein dafürhalten, ist die Variante über eine Session zu aufwendig.

              Aufwendig ist sie nicht. session_start() und ein paar Zugriffe auf $_SESSION. Fertig. Aber ...

              Wie genau könnte denn deine Session-Lösung aussehen?
              Würde mich mal interessieren, vielleicht ist sie ja wirklich besser und ich habe direkt noch etwas dazu gelernt.

              ... sie hat Nachteile im Zusammenhang mit dem Browser-Cache. Der Browser sieht bei verschiedenen Suchanfragen immer dieselbe URL und holt dann womöglich das falsche Ergebnis aus seinem Cache und nicht das gewünschte vom Server. Das Cachen ganz zu verbieten ist auch nicht so prickelnd.

              Lo!

              1. Ich habs jetzt mit hidden feldern gelöst, denke die lösung ist im allgemeinen ganz gut wenn man viele einschränkungen oder variable einschränkungen hat.

                amazon gibt es zb in der url mit beim link hab ich gesehen, jedoch ist das oft nur das stichwort oder noch 2-3 einschränkungen, da ich jedoch variable einschränkungen hab passt das mit hidden sehr gut.

                vielen dank

      2. Hi!

        Jetzt hab ich noch ein Problem. Die $_POSTS für die such query muss ich mir ja irgendwie merken wenn ich jetzt zb. auf seite 2 gehe oder seite 3 und wieder zurück. Gibts da noch nen trick?

        Du veränderst mit einer Suche keine Daten, also ist es nicht notwendig, POST zu verwenden. Nimm GET für die Parameter und die Seitenzahl. GET hat auch den Vorteil, dass man mit den Browser-Funktionen in den bereits abgefragten Seiten vor und zurück blättern kann, ohne von einem "Wollen Sie das Formular nochmal abschicken?" genervt zu werden. Auch die bereits genannte Session ist _keine_ gute Idee, da mit immer gleich bleibender URL für verschiedene Suchvorgänge verschiedene Daten kommen. Am besten ist es so umgesetzt, dass mit GET und Parametern, egal wie und zu welcher Zeit der Aufruf erfolgt, stets dasselbe Ergebnis für dieselbe URL geliefert wird. Dann kann man auch mal solche URLs bookmarken oder weiterversenden.

        Wenn du dich nun entschieden hast, auf GET zu setzen, dann hast du bereits alle Daten in der aktuellen URL, nur die Seite musst du für die Blätter-Links ändern. Dazu empfiehlt es sich, mit parse_str() den Query-String in ein Array zu parsen, den Seitenwert zu ändern und ihn dann mit http_build_query() wieder zusammenzubauen. http_build_url() ist auch einen Blick wert (wobei sich diese Funktion in einer PECL-Extension versteckt und damit nicht unbedingt verfügbar sein muss).

        Lo!

    3. Hi,

      SQL_CALC_FOUND_ROWS ist dein Stichwort.

      Aber teste es dann mal, ob es wirklich schneller ist.

      Lies mal die Kommentare hier.

      Gruß, Torro

      1. Hello,

        SQL_CALC_FOUND_ROWS ist dein Stichwort.

        Aber teste es dann mal, ob es wirklich schneller ist.

        Lies mal die Kommentare hier.

        Die Kommentare und auch der Artikel speigeln wider, dass sich wieder mal keiner WIRKLICH Gedanken um dynamische Datenbestände macht.

        Setzen wir mal voraus, dass das ganze im Webumfeld auf einer gut besuchten Seite geschieht, und ein Datanbestand abgefragt werden soll, der auch durch Useraktion/-interaktion beeinflusst, also mindestens ergänzt (a), ggf. auch verändert (c) oder reduziert (b) werden kann.

        Wenn man nun ein Query baut, müsste man sich also sowieso zuerst entscheiden, ob der User (nach Microsoftsprache) einen Snapshot oder ein Dynaset als Antwort erhalten soll. Denn während sich der User einen Teil der Daten anschaut, fügen andere User schon Datensätze hinzu (a) oder löschen welche (b).

        Wenn man nun die Variante (2) des Artikels benutzt, müsste man wissen, ob sich zwischen der Datenabfrage und der Ermittlung der Datenmenge etwas verändert hat und ob sich ziwschen dem ersten Request des Users auf das Interface und dem nächsten ggf. nochmals etwas geändert hat am Datenbestand.

        Das Ganze führt dann schlussendlich in einer http/s-Umgebung, in der User WISSEN MÜSSEN, ob es Veränderungen gegeben hat automatisch zur Variante (4), in der man zuerst alle IDs zur Query in der gewünschten Sortierung (also nach Daten) besorgt, und dann erst die passende Datenmenge (Offset/Limit) mit Hilfe der zwischengespeicherten Menge der IDs abfragt. Zusätzlich muss der User dann bei jedem Request über die Menge der hinzugefügten IDs informiert werden. Die gelöschten können einfach in der Detailanzeige mit "Datensatz wurde inzwischen gelöscht" anstelle der Daten berücksichtigt werden.

        Noch komplexer wird das Ganze, wenn man nun auch noch Veränderungen in der Sortierung durch zwischenzeitliche Datenveränderungen (c) berücksichtigen muss, zumindest durch geeignete Markierung in der Detailanzeige. Denn sonst würde der Front-End-User nicht verstehen, dass nach siebzehn  "Meier" plötzlich ein "Abraham" folgt und es dann aber wieder mit "Meier" weitergeht.

        Je mehr die "Webtechnologie" in tägliche Applikationen von Betrieben und Behörden einzug hält, desto mehr muss man sich auch diesen Fragen stellen!

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

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

        SQL_CALC_FOUND_ROWS ist dein Stichwort.
        Aber teste es dann mal, ob es wirklich schneller ist.
        Lies mal die Kommentare hier.

        Performance-Messungen sind immer mit Vorsicht zu genießen. Besonders bei einem System wie einem DBMS, das unterschiedlich komplexe Abfragen unterschiedlich optimieren kann, sollte man sich nicht auf die Generalität eines Messergebnisses, möglicherweise noch aus einer früheren/anderen Version, verlassen. Und ganz wichtig: Solange sich kein Performance-Engpass abzeichnet, ist jede Zeit, die für Mikrooptimierung draufgeht, unnötig verschwendet. Mit Mikrooptimierung bekommt man nur sehr wenig freie Ressourcen zurück. Bei einem hohen Ansturm braucht man aber üblicherweise viel mehr Spielraum als die MO liefern kann.

        In den Kommentaren des Artikels ist ein Verweis auf einen anderen ähnlich alten Artikel zu finden, in dessen Kommentaren etwas von einer Verbesserung und auch gegensätzlichen Messergebnisses zu lesen ist.

        Lo!