MySQL - Zufallsausgabe von Datensätze beeinflussen

proloser

Erfahrenes Mitglied
Hallo,

ich möchte mein Zufallsgenerator mit verschiedenen Werten beeinflussen, ist das überhaupt möglich?


Beispiel Datenbank:

id | wert | text
-------------------
1 | 20 | Test 1
2 | 12 | Test 2
3 | 89 | Test 3
4 | 30 | Test 4


Wenn ich das Script 100 mal aufrufe soll sich das zB so aufteilen:

ID: 3 = 40 aufrufe
ID: 4 = 30 aufrufe
ID: 1 = 20 aufrufe
ID: 2 = 10 aufrufe

Wichtig ist mir also, umso höher der Wert, desto öfter wird der Datensatz angezeigt.


Derzeit werden die Datensätze einfach Zufällig ausgegeben:
Code:
SELECT
  * 
FROM 
  `table`
ORDER BY 
  RAND()

Ich wäre für Lösungsvorschläge oder Ansätze sehr dankbar.

Gruß proloser
 
Zuletzt bearbeitet:
Moin proloser,

da habe ich keinerlei Skrupel, meine Naivität mal als erster hier im Forum auszubreiten...

Mein erster (und bislang mutterseelenallein gebliebener) Gedanke war:

Hey, wenn das Skript sich beim 75sten oder beim 99sten Mal in deinem Sinne "richtig" verhalten soll, dann musst du es dir wohl (oder übel) in deiner Tabelle "merken", dass schon 74 oder 98 Aufrufe vorher da waren und was noch angezeigt werden soll/was schon oft genug angezeigt wurde.


Was ist denn um Gates Willen der real existierende Anwendungsfall?
Willst du Sponsoren-Werbung anzeigen... und einer zahlt 3000 Euro/Tag und ein anderer nur 2500?

Grüße
Biber
 
Nicht ganz. Ich möchte die Banner, die ich auf meiner Webseite schalte praktisch eine Priorität geben, damit bestimmte öfter angezeigt werden.

Erstmal danke für den Beitrag, ich werd es mal versuchen umzusetzen.
 
Ich würde die Tabelle um eine Spalte erweitern. Diese Spalte enthält einen Wert zwischen 0.0 und 1.0.

id | wert | text | wert2
----------------------------
1 | 20 | Test 1 | 0.13245033112582781457
2 | 12 | Test 2 | 0.21192052980132450331
3 | 89 | Test 3 | 0.80132450331125827815
4 | 30 | Test 4 | 1.0

20+12+89+30 = 151

20/151 = 0.13245033112582781457
32/151 = 0.21192052980132450331
121/151 = 0.80132450331125827815

Abfrage:

SQL:
SELECT * FROM tabelle WHERE wert2 > RAND() ORDER BY wert2 ASC LIMIT 1;

Edit: Bestimmt lässt sich das auch während der Abfrage aus "wert" berechnen.
 
Zuletzt bearbeitet:
Moin CPoly,

warum dann nicht sogar nur
SQL:
SELECT * FROM tabelle
 ORDER BY wert2*RAND() DESC 
LIMIT 1;

Grüße
Biber
 
Wegen Performance. ORDER BY RAND() ist langsam, da für jede Spalte erstmal ein Zufallswert erstellt werden muss und anschließend nach diesem sortiert wird, was ohne Index (den der Wert ja nicht haben kann) sehr lange dauert.

Bei meinem Ansatz wird zwar ebenfalls für jede Zeile eine neuer Zufallswert erzeugt (was nicht gewünscht ist, dazu komme ich gleich), aber danach wird nicht sortiert.

Zur Verbesserung meiner Lösung sollte man wohl besser so vorgehen:
(Denn sonst kommt es zu unerwünschten Ergebnissen.)

SQL:
SET @rnd:=RAND();
SELECT * FROM tabelle WHERE wert2 > @rnd ORDER BY wert2 ASC LIMIT 1;

Deine Lösung erfordert aber für jede Zeile einen andere Zufallswert, sonst funktioniert sie nicht.
 
Vielen Dank für die Vorschläge. Ich habe jetzt noch versucht den Wert2 während der Abfrage zu berechnen aber so wie ich mir das Vorstelle funktioniert es nicht.

Code:
SET @rnd:=RAND();
SELECT *,  wert / SUM(wert) AS wert2 FROM tabelle WHERE wert2 > @rnd ORDER BY wert2 ASC LIMIT 1;

Wert2 ergibt 1, warum?
 
Wert2 ergibt 1, warum?

Dadurch, dass du die Aggregatfunktion SUM() auf die Spalte "wert" anwendest, wird dein Ergebnis automatisch gruppiert, da Aggregatfunktionen nur dann zulässig sind.

Wenn du es innerhalb der Abfrage machen willst, dann mittelf Subselect.

Noch was: Wenn du dir die Werte ansiehst, welche ich in meinem ersten Post errechnet habe, siehst du, dass deine Berechnung ohnehin nicht korrekt ist. Ich habe nicht einfach den Quotienten gebildet, sondern der Wert der vorherigen Spalte wird mit einbezogen. Die Werte in der Spalte "wert2" müssen unbedingt den Wertebereich bis 1 komplett füllen, sonst klappt es nicht.
 
Zuletzt bearbeitet:
Stimmt das hab ich übersehen.
Ich werd jetzt versuchen ob ich das mit dem Subselect hinbekomme, aber wie ich an den wert vom nächsten Datensatz komme, werd ich nochmal eure Hilfe brauchen.
 
Wie häufig ändern sich denn die Werte in der Spalte "wert"? Wenn das nur ab und zu mal passiert, kannst du doch "wert2" schon vorher berechnen, immer dann, wenn du auch "wert" änderst.

Aber wenn es sich nicht um sehr viele Daten handelt, tut es der Einfachheit halber auch die Lösung mit dem ORDER BY wert*RAND(). Aber mit "wert" nicht mit "wert2", wie Biber2 es vorgeschlagen hat (fällt mir jetzt erst auf).
 

Neue Beiträge

Zurück