Robert: Zufällige Abfrage!

Hi,

Ich habe eine Datenbank voller Datensätze. Jetzt will ich aus der einen Datensatz per Zufall abrufen.

Habe die Funktion rand() gesehen, komme aber nicht wirklich klar damit.

wie baue ich das am besten in ein select ein, dass ich genau einen datensatz erhalte.

zusätzliche schwierigkeit: diesen datensatz muss es auch geben (also nicht nach id arbeiten, da primärschlüssel fehlen kann: 1,2,3,5,8, ...), und in der where-klausel muss visible=1 vorkomme.

thx im vorraus

  1. Halihallo Robert

    Ich habe eine Datenbank voller Datensätze. Jetzt will ich aus der einen Datensatz per Zufall abrufen.

    Welche Datenbank? - MySQL? MSSQL? ...

    Habe die Funktion rand() gesehen, komme aber nicht wirklich klar damit.

    Aber in der richtigen Ecke bist du schon mal gelandet.

    wie baue ich das am besten in ein select ein, dass ich genau einen datensatz erhalte.

    if (MySQL) {
       Direktive LIMIT verfügbar
    } else {
       Evtl. TOP verfügbar o. ä.
    }

    mit LIMIT bzw. TOP kannst du einen Record auswählen, über RAND kannst du einen zufälligen
    Index auswählen.

    zusätzliche schwierigkeit: diesen datensatz muss es auch geben (also nicht nach id arbeiten, da primärschlüssel fehlen kann: 1,2,3,5,8, ...), und in der where-klausel muss visible=1 vorkomme.

    Das wird schon wesentlich schwieriger. Mit LIMIT und einem gültigen Index erhälst du
    zwar _immer_ einen Record, aber über RAND ohne Subqueries hast du keine Möglichkeit; den
    grösstmöglichen Index zu definieren. Kannst du auf eine serverseitige Programmiersprache
    ausweichen?

    Viele Grüsse

    Philipp

    1. sry, vergessen: mysql verwende ich.
      und ja, ich kann auf php zurückgreifen, allerdings glaube ich wird das bei mehreren 1000 datensätzen recht langsam :(
      (vor allem mit meinem programmierstil)

      mfg
      robert

      1. Halihallo Robert

        sry, vergessen: mysql verwende ich.
        und ja, ich kann auf php zurückgreifen, allerdings glaube ich wird das bei mehreren 1000 datensätzen recht langsam :(

        Meine Güde, bestimmt nicht jeden Record durchforsten! - Alles was du brauchst, ist ein
        Query, der die Anzahl aller Records ausgibt:

        SELECT COUNT(*) FROM <tabellen_name>

        und einen Query, wo du den zufalls-Record ausliest:

        SELECT * FROM <tabellen_name> WHERE visible=1 LIMIT $anzahl, 1

        wobei du für $anzahl diejenige Anzahl Records einfügst, welche du aus dem ersten Query
        gewinnen kannst.

        Viele Grüsse

        Philipp

        1. Hi, Philipp,

          mit MS SQL Server 2000 geht's aber nicht. - Oder weisst Du auch da einen Trick?

          Gruss,
          Lude

          1. Halihallo Lude

            mit MS SQL Server 2000 geht's aber nicht. - Oder weisst Du auch da einen Trick?

            Ich kenne mich mit MSSQL nicht aus, jedoch folgender Ansatz:

            SELECT TOP 1 FROM (
               SELECT *
                  FROM <tabellen_name>
                  ORDER BY RAND()*9999999;
            )

            Aber AFAIK wird RAND() für jeden Query nur einmal berechnet, du wirst also immer den
            ersten Datensatz bekommen (obwohl dieser bei vielen Lösch- und Einfügeoperationen auch
            schon zufälligen Charakter hat). Leider bin ich mir dessen nicht sicher, also schlage
            ich vor, du versuchst es einmal oder liest die Doku zu RAND.

            Oder du musst auch auf die Programmiersprache ausweichen und dort ein Kriterium (Primary
            Key) zur zufälligen selektierung von Records finden (eg. alle Primaries in eine Liste
            einlesen und dann wahlweise einen benutzen; oder den Resultset-Cursor auf einen
            zufälligen Record weisen lassen; falls dein System/Library die Verwendung von Cursors
            unterstützt).

            Viele Grüsse

            Philipp

            1. Hi,

              Oder du musst auch auf die Programmiersprache ausweichen und dort ein Kriterium (Primary
              Key) zur zufälligen selektierung von Records finden (eg. alle Primaries in eine Liste
              einlesen und dann wahlweise einen benutzen; oder den Resultset-Cursor auf einen
              zufälligen Record weisen lassen; falls dein System/Library die Verwendung von Cursors
              unterstützt).

              nur zur Info: Ich realisiere es indem ich alle GUIDs in eine temporaere Tabelle schreibe, die ein hochzaehlendes ID-Datenfeld hat. Dann kommt ein "ID=RAND von COUNT(*)" und der zufaellige Datensatz ist gefunden. Wenig elegant.

              Gruss,
              Lude