yeahns: MySQL-Abfrage zufällig - aber nun doch nicht!

Hi,

ich habe ein kleines Fotoalbum programmiert (mit MySQL). Auf der Startseite liste ich jeden Ordner, oder "Album" mit kleinen Thumbs auf. Das mach ich mit der Abfrage:

$result=MYSQL_QUERY("SELECT * FROM fotos LEFT JOIN fotos_ordner ON fotos.ordner = fotos_ordner.schl WHERE schl='$i'")

wodurch sich in $result alle Datensätze, die sich im Ordner $i befinden, befinden.

Da längst zuviele Fotos in der Datenbank sind, will ich auf der Startseite nur jeweils 10 Fotos pro Album anzeigen. Also breche ich die Schleife

while($row = mysql_fetch_assoc($result))

einfach nach dem 10ten Durchlauf ab. So weit, so gut.

Da ich natürlich nicht will, dass auf der Startseite die restlichen Fotos unterschlagen werden, habe ich an den MYSQL_QUERY noch "ORDER BY RAND()" angehängt. Funktioniert bestens. Nun mein Problem:

Es sieht natürlich nicht so fein aus, wenn bei jedem Reload die innere Abfolge der Bilder verändert ist, vor allem bei denen Alben, die gar nicht erst 10 Bilder enthalten, denn es werden bei Reload keine neuen Bilder angezeigt, nur die Reihenfolge geht kaputt.

Ich hätte es lieber, dass 10 Bilder aus jedem Album zufällig ausgewählt werden, aber die interne Reihenfolge (am besten ganz einfach über die id) erhalten bleibt. Also zum Beispiel dasjenige der 10 Bilder mit der höchsten id zuerst!

Gibt es da eine Möglichkeit, das in den MYSQL_QUERY einzubauen?

Danke für alle Antworten schonmal,
Jens

  1. Ich hätte es lieber, dass 10 Bilder aus jedem Album zufällig ausgewählt werden, aber die interne Reihenfolge (am besten ganz einfach über die id) erhalten bleibt. Also zum Beispiel dasjenige der 10 Bilder mit der höchsten id zuerst!

    Du solltest schon mit der LIMIT-Klausel kommen um nicht alle Datensätze vom (Daten-)Server zu holen, ausserdem musst Du die Reihenfolge irgendwo speichern, wenn Du diese erhalten willst.

    Das könntest Du also in eine Session-Variable schreiben oder eine Datentabelle, aber da ja auch Fotos hinzukommen können oder gelöscht werden könnten müsstest Du noch ein "HasChanged"-Flag speichern.

    So richtig sexy wäre das dann aber nicht.

    1. So richtig sexy wäre das dann aber nicht.

      Kommt hier wohl ganz stark auf die Fotos an, denke ich...

    2. Hi, danke für die Antwort!

      Ich möchte eigentlich keine Tabellen anlegen oder ähnliches, habe nicht mehr so viel Zeit für MySql, ich brauche die für PHP, muss bald fertig werden.

      Okay, das mit der Limit Klausel habe ich eingebaut, jetzt muss ich die Schleife nicht mehr unterbrechen, da sie von selbst bei 10 aufhört!
      Allerdings wählt die Datenbank immer die gleichen 10 bilder aus den Alben aus.
      Ich möchte aber, um es nochmal deutlich zu formulieren, 10 bilder ZUFÄLLIG auswählen (das funktioniert ja gut, wenn ich ORDER BY RAND() angebe) und diese dann IN FEST VORGEGEBENER REIHENFOLGE (z.b. nach id, oder "eingetragen am") auf der Seite anzeigen. Also sollten die in $result schon geordnet liegen.

      Wäre super, wenn du mir sagen könntest, wie man das macht, du scheinst ja ziemlich Ahnung zu haben (Session-Variable sagt mir z.B. nichts). Und das MYSQL Handbuch ist viel zu kompliziert, da steig ich nicht durch!

      Lg
      Jens

      1. Okay, das mit der Limit Klausel habe ich eingebaut, jetzt muss ich die Schleife nicht mehr unterbrechen, da sie von selbst bei 10 aufhört!
        Allerdings wählt die Datenbank immer die gleichen 10 bilder aus den Alben aus.
        Ich möchte aber, um es nochmal deutlich zu formulieren, 10 bilder ZUFÄLLIG auswählen (das funktioniert ja gut, wenn ich ORDER BY RAND() angebe) und diese dann IN FEST VORGEGEBENER REIHENFOLGE (z.b. nach id, oder "eingetragen am") auf der Seite anzeigen. Also sollten die in $result schon geordnet liegen.

        Geht sowas:
         "ORDER BY id ASC, RAND"
        ?

        Anonsten (Skizze):

        SELECT
         *
        FROM
         (
         SELECT
          *
         FROM
          DT1
         ORDER BY
          RAND
         ) Temp
        ORDER BY
         id ASC

        1. Hallo,

          ich habe beide Varianten probiert, leider mit dem gleichen Ergebnis wie vorher. Die zweite Variante hab ich noch umgeschrieben in

          $result3 = MYSQL_QUERY("CREATE TEMPORARY TABLE temp SELECT * FROM fotos
              LEFT JOIN fotos_ordner ON fotos.ordner = fotos_ordner.schl WHERE
              schl='$i' ORDER BY RAND() LIMIT 10)");

          $result3 = MYSQL_QUERY("SELECT * FROM temp ORDER BY zeitpunkt_dbEntry DESC");

          while ($row = @mysql_fetch_assoc($result3)) {
          ...
          ...

          Leider wieder das gleiche Problem. Es lässt sich damit wohl darauf schließen, dass die temporäre Tabelle erstellt wird. Auch darauf, dass sie zufällig aus allen Bildern des Ordners aussucht.
          Aber warum kann ich mit der zweiten Abfrage nicht die Werte sortiert aus der temporären Tabelle auslesen? Die Sortierung klappt ja mit genau der Syntax, wenn ich aus einer konstanten Tabelle auslese!

          Lg
          Jens

          1. Versuch mal Variante 2, die funzt sicher, wenn Du es richtig anstellst. Arbeite mit Sub-SELECTs, konsultiere ggf. die Doku, erstelle keine temporären Hilfstabellen, das macht MySQL automatisch wenn Du der korrekten Sub-SELECT Syntax folgst.

            1. Versuch mal Variante 2, die funzt sicher, wenn Du es richtig anstellst. Arbeite mit Sub-SELECTs, konsultiere ggf. die Doku, erstelle keine temporären Hilfstabellen, das macht MySQL automatisch wenn Du der korrekten Sub-SELECT Syntax folgst.

              Also, es will einfach nicht klappen. Ich hab das mal in phpmyadmin eingegeben:

              SQL-Befehl:

              SELECT *
              FROM (

              SELECT *
              FROM fotos
              LEFT JOIN fotos_ordner ON fotos.ordner = fotos_ordner.schl
              WHERE schl =120
              ORDER BY id
              )temp
              ORDER BY id
              LIMIT 0 , 30

              MySQL meldet:
              #1064 - You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM fotos LEFT JOIN fotos_ordner ON fotos . ordner =

              Es ist über Version 5 installiert! Sub Selects müssen also, wie im netz zu lesen ist, problemlos funktionieren. Ist an der Syntax was auszusetzen? ich hab auch schon mal das "temp" hinter der Klammer weggelassen, weil ich das so auch im web gesehen habe, kam aber aufs gleiche raus.

              1. Betrachte die Sache doch mal ganz abstrakt:
                1.) Du möchtest eine zufällig augewählte Datensatzmenge der Grösse 10
                2.) Diese möchtest Du sortiert ausgeben
                3.) Die Sortierung beisst sich anscheinend mit "ORDER BY RAND"
                4.) Wir lösen die Abfrage "SQL-menegenbasiert" mit einem Sub-SELECT indem wir erst die 1 beschriebene Menge holen und als Zielobjekt des äusseren SELECTs definieren, das die Sortierung besorgt

                Versuche mal in Einzelschritten an die Sache ranzugehen, die zufällig ausgewählte Datensatzmenge hast Du doch schon jetzt mache auf die per Sub-SELECT die SOrtierung.