Seitencounter ohne 2 SQL Abfragen?
Manuel Böttcher
- php
0 dedlfix0 Alexander (HH)0 shn
Hallo Allerseits, ich stehe mit einem Problem irgendwie im Wald..
Beispiel:
Ich habe eine mysql Tabelle mit sagen wir mal x tausend Einträgen und
will die 2000 haben deren Wert im TabFeld 'A'>500 ist.
(Nur so als Beispiel)
Das ganze soll seitenweise dargestellt werden, sagen wir 50 Einträge
je Seite. Um die Seitenzahlen zum Blättern zu berechnen brauche ich
die Gesamtzahl aller relevanten Datensätze, also:
select count(*) from tabelle where A>'500'
Da ich nun nur 50 Sätze ausgeben will muss ich noch ein zweites mal
die selbe Abfrage machen, diesmal mit der Limit Klausel, also:
select name from tabelle where A>'500' limit $aktueller_seitenzaeler, 50
Das funkt auch alles und ist nicht mein tatsächliches Problem.
Ich weiß auch das ich die Limit Klausel sparen könnte und den Gesamt-Counter
aus der Anzahl der im Ergebnis enthaltenen Datensätze ziehen kann und ich dann aus dem Gesamt-Datenrecord nur die Sätze
$aktueller_seitenzaehler bis 50 auslese. Somit würde ich mir die Abfrage
des Counters sparen.
Diese Variante mißfällt mir jedoch da das Datenrecord, deswegen mein Beispiel,
sehr groß sein kann und Sätze enthält die ich
eigentlich nicht zur Darstellung brauche.
Bei meinem aktuellen Projekt kommt noch hinzu das die SQL Anfrage
sehr komplex ist - und demzufolge auch die Datenbank ein wenig mehr
beschäftigt ist weswegen ich einen Weg suche die doppelte Anfrage, nur des
Counters wegen, zu umgehen.
Mit fällt nichts mehr ein.. :-(
Vielleicht habt ihr eine Idee, wäre toll, aber ich fürchte das
es keinen anderen Weg gibt?
Manuel
echo $begrüßung;
Um die Seitenzahlen zum Blättern zu berechnen brauche ich die Gesamtzahl aller relevanten Datensätze, also:
select count(*) from tabelle where A>'500'
Da ich nun nur 50 Sätze ausgeben will muss ich noch ein zweites mal die selbe Abfrage machen, diesmal mit der Limit Klausel, also:
select name from tabelle where A>'500' limit $aktueller_seitenzaeler, 50
Um zwei Statements wirst du nicht herumkommen, aber du kannst das erste weglassen und dem zweiten ein SQL_CALC_FOUND_ROWS spendieren (SELECT SQL_CALC_FOUND_ROWS ... FROM ... LIMIT ...). Damit werden zusätzlich zu den limitierten Datensätzen die Anzahl aller Datensätze ohne Limit errechnet und für eine anschließende Abfrage mittels SELECT FOUND_ROWS() bereitgestellt.
echo "$verabschiedung $name";
echo $begrüßung;
Um zwei Statements wirst du nicht herumkommen, aber du kannst das erste weglassen und dem zweiten ein SQL_CALC_FOUND_ROWS spendieren (SELECT SQL_CALC_FOUND_ROWS ... FROM ... LIMIT ...). Damit werden zusätzlich zu den limitierten Datensätzen die Anzahl aller Datensätze ohne Limit errechnet und für eine anschließende Abfrage mittels SELECT FOUND_ROWS() bereitgestellt.
echo "$verabschiedung $name";
Hallo,
habt vielen Dank für die Tipps. FOUND_ROWS() schau ich mir an.
In Sachen Normalisierung habe ich mir im Vorfeld schon sehr viel
Mühe gegeben, ich denke das haut hin.
Eine Mögliche Variante wäre auch den Counter nur zu jeder neuen
Suchanfrage zu aktualisieren (also nur einmal zu ermitteln). Mittels
einer vergleichenden SuchanfragenID per Session gespeichert müsste das ja gehen.
Zwar wären dann neu hinzu kommende passende Sätze nicht enthalten
aber damit kann ich im praktischen Teil leben.
Manuel
yo,
wenn du nur wirklich eine abfrage haben willst, benutze den UNION ALL operator und "klebe" die beiden abfragen zusammen, noch klug sortiert, dann enthält der erste datensatz immer die anzahl und der rest sind die datensätze mit den eigentlich ergebnissen der jeweiligen seite.
Ilja
yo,
wenn du nur wirklich eine abfrage haben willst, benutze den UNION ALL operator und "klebe" die beiden abfragen zusammen, noch klug sortiert, dann enthält der erste datensatz immer die anzahl und der rest sind die datensätze mit den eigentlich ergebnissen der jeweiligen seite.
Ilja
Na ja, dann würde das ja so aussehen:
select count(*) form table where $whereKram UNION ALL select * from table where $whereKram limit 0,50
Dann wäre ja die DB 2x mit den where Klauseln beschäftig was ich ja vermeiden will oder habe ich da was falsch verstanden?
Übrigens mit FOUND_ROWS() rennt das ganze. :)
yo,
select count(*) form table where $whereKram UNION ALL select * from table where $whereKram limit 0,50
das geht schon mal gar nicht und wird mit grosser wahrscheinlichkeit einen syntax-fehler hervorrufen. bei einem UNION muss die anzahl der spalten gleich sein. zum anderen macht eine ausgabe mit dem joker * im produktiven einsatz nur selten sinn. besser ist es meistens explizit die gewünschten spalten anzugeben.
SELECT COUNT(*) Spaltenalias1, NULL Spaltenalias2, NULL Spaltenalias3, 0 Spaltenalias4
FROM table
WHERE .....
UNION ALL
SELECT spalte1, spalte2, spalte3, 1
FROM table
WHERE....
ORDER BY 4
Dann wäre ja die DB 2x mit den where Klauseln beschäftig was ich ja vermeiden will oder habe ich da was falsch verstanden?
du musst zwei dinge unterscheiden, zum einen hast du die aufrufe von php an den datenbankserver. mit UNION ALL hast du davon nur einen und auch nur ein resultset, was wieder zurück geliefert werden muss. mit FOUND_ROWS() hast du derlei zwei aurufe und rückgaben.
und was das dbms betrifft, so kann es selbst aus nur einer where klausel intern mehrere abfragen daraus machen.
Ilja
Moin Moin!
Du könntest das gesamte Suchergebnis auf einen Schlag in eine Session packen und die DB-Abfrage so komplett vermeiden. Bleibt nur die Frage, was Dein Session-Manager zu der Idee meint. ;-)
Du könntest die Suche vereinfachen, indem Du Views einsetzt, die die Tabellen schon einmal zusammenführen, und dann zwei SELECTs auf die Views machst.
Du könntest überlegen, ob Deine Datenbank in 3. Normalform ist. Das macht Suchabfragen im Allgemeinen wesentlich übersichtlicher.
Alexander
Servus,
SQL_CALC_FOUND_ROWS in Kombination mit FOUND_ROWS().
Gruss
Patrick