benachbarte Einträge auslesen / vor+zurück

Begonnen von kenny, 14. November 2007, 12:58:44

Vorheriges Thema - Nächstes Thema

kenny

Hallo zusammen.
Habe mir ein Galleriescript gebastelt. Bin soweit auch ganz zufrieden.. Unter dem jeweiligen Bild, möchte ich dem Besucher die Möglichkeiten geben zum ersten Bild in der Gallerie, zum vorherigen, zum nächsten und zum letzten zu blättern. Also genau wie bei Powies PImage. Bisher nutze ich dafür ganze 4 Querys:
 


fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                           WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                 id fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                          WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                id fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                           WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                 id > \".$bild[\'id\'].\"\'
                           ORDER BY id ASC  
                           LIMIT 1\");
$last = $sql->fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                          WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                id > \'\".$bild[\'id\'].\"\'
                          ORDER BY id DESC  
                          LIMIT 1\");    
?>

 
 
Ich finde 4 Querys... für so ein kleine dumme Blätterfunktion aber ziemlich übertrieben..
Geht das nicht besser? Ich habe keine Ahnung, wie man sowas zu weniger querys zusammenfassen könnte.
Danke für Hilfe.

Powie

das ist wirklich eine \"beschissene\" Sache, da das ja auch von der Art der Sortierung bei mir abhängig ist. Ich habe da auch noch keine saubere Lösung gefunden so das es immer funktionieren würde.....

k00ni

Optimierungen vom Code her gibt es. Von der Idee dahinter, da komm ich gerade auf nichts.
Folgendes könnte man zusammenfassen:
 

$first = $sql->fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\" 
                           WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                 id fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                          WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                id fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                           WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                 id > \".$bild[\'id\'].\"\'
                           ORDER BY id ASC  
                           LIMIT 1\");
$last = $sql->fetch_array(\"SELECT id FROM \".$db[\'tab\'][\'bild\'].\"
                          WHERE catid = \'\".$bild[\'catid\'].\"\' and
                                id > \'\".$bild[\'id\'].\"\'
                          ORDER BY id DESC  
                          LIMIT 1\");

 
 
Mach dir einfach eine switch-Anweisung und modifiziere den SQL-String je nachdem, was abgefragt werden muss. Ich denke, es werden nur die ORDER-BY-Klauseln ersetzt und einmal das größer oder kleiner - Zeichen beim Vergleich der Bildid\' s.
Was mich beim ersten und letzten wundert. Liest du die Id des letzten und ersten Bildes gesondert aus oder wie kommst du darauf? An sich könnte man diese beiden für sich selbst noch anpassen. Und zwar MAX, MIN auf die Bildid angewendet und dann mittels ASC, DESC und LIMIT, sowohl die Sortierung angepasst, als auch die gleich die Auswahl auf nur ein Element beschränkt. So hätte man dann gleich das letzte oder erste Element. Vorausgesetzt, dass die Bildid der Primärschlüssel ist und es keine anderen Schlüssel für die Bild gibt.

Man könnte Subselects für sowas verwenden. Ungefähr so:

SELECT 
   *
FROM
   `kin`
WHERE
id = $id
OR id = (
           SELECT MIN(id) FROM kin
       )
OR id = (
           SELECT MAX(id) FROM kin
       )
OR id = (
           SELECT MAX(id) FROM kin WHERE id  $id ORDER BY id DESC
       )
ORDER BY
   id ASC

 
(kin ist hierbei nur ein Beispiel)
Immer kritsch ist jedoch, wenn die ausgewählte Id bereits die höchste oder niedrigste in der Datenbank ist. Dann erhält man nämlich u.U. nur drei Ergebnisse zurück.

kenny

Okay. Vielen Dank erstmal. Die Idee mit den Subselects ist nicht schlecht. Aber dann muss ich das Ergebniss ja mit einer while-schleife durchlaufen. Das dauert ja auch. Ist das wirklich besser als 4 einzelne querys, die nur je einen Datensatz ausgeben? Ich finde meine bisherige version auch irgendwie aufgeräumter.
Trotzdem Danke für die Idee.

Aber dann muss ich das Ergebniss ja mit einer while-schleife durchlaufen. [/quote]
Das musst Du bei deiner Version doch auch. Oder wie liefert fetch_array() die Beiträge?
Ist das wirklich besser als 4 einzelne querys, die nur je einen Datensatz ausgeben?[/quote]
Insofern ja, als das nur ein Recordset erzeugt und übertragen werden muss. MySQL intern ist natürlich wesentlich performanter als vier mal mit PHP über ein einzeiliges Result-Set zu iterieren. Das sind aber nur Vermutungen - man müsste es benchmarken.
Insgesamt wäre es vielleicht sinnvoll, eine Nested-Set-Struktur abzubilden.

all your base are belong to us