Bist du bereit für einen anderen Ansatz? Der relativ kompliziert aussieht, es aber nicht ist?
Also, meine Idee.
1) Sortieren der Daten nach dem Wert absteigend und die Reihenfolge (Zeilennummer) bestimmen. Dann hat der höchste Wert die Höchste rownum.
2) Pro Datensatz Anzahl rownum Datensätze erstellen. Also in deinem Beispeil 4 Datensätze für id3, 3 Datensätze für id4 etc.. Gibt in deinem Beispiel am Ende 10 Datensätze.
3) Zufälligen id aus diesen Daten nehmen
Und so könnte es aussehen (meine Tabele heisst test_rnd)
Alles mit @sind Variablen. Siehe dazu die MySQL-Doku
Beginne ich ganz innen mit der Erklärung. Ich starte mit 2 SELECT
STEP 1
SUBSELECT dat1:
Dies ist ein normales Konstrukt um mittels Variablen Zeilennummern zu vergeben. Ich habe vorgängig im zweiten Subselect die Daten nach dem Wert sortiert, damit der höchste Wert auch die höchste Zeilennummer kriegt
Ausgabe:
STEP 2
SUBSELECT dat2:
In dat2 kombiniere ich mein Resultat von dat1 mit meiner Tabelle. Dabei gebe ich keine Join-Bedinung an. Ergo gibt es COUNT(test_rnd)*COUNT(test_rnd) Zeilen. Mehr Zeilen als wir brauchen.
Darum zähle ich für jede ID, wieviel mal sie bereits vorgekommen ist (startend mit 0).
Für jeden Datensatz wird ein Feld ´Flag´ erstellt. Ist dier Counter (@cnt) gleich oder höher der rownum, so wird dieses Flag auf 0 gesetzt. Somit gibt es in unserem Beispiel für id3 4 Datensätze mit Flag 1, für die id4 sind es 3 etc.
Das Resultat sieht dann so aus
STEP 3
Zufallszahl und Endfilter
in dat2 haben wir das Flag erstellt, welches uns sagt ob uns der Datensatz interessiert. Nach diesem filtern wir nun.
Das ergibt ein Resultat
Diese Daten nun noch zufällig sortieren und den ersten Wert auslesen....
Also, meine Idee.
1) Sortieren der Daten nach dem Wert absteigend und die Reihenfolge (Zeilennummer) bestimmen. Dann hat der höchste Wert die Höchste rownum.
2) Pro Datensatz Anzahl rownum Datensätze erstellen. Also in deinem Beispeil 4 Datensätze für id3, 3 Datensätze für id4 etc.. Gibt in deinem Beispiel am Ende 10 Datensätze.
3) Zufälligen id aus diesen Daten nehmen
Und so könnte es aussehen (meine Tabele heisst test_rnd)
SQL:
SELECT
dat2.id
FROM
(
SELECT
@cnt := IF(@last_rownum = dat1.rownum, @cnt+1, 0) AS cnt,
(@cnt < dat1.rownum) AS flag,
@last_rownum := dat1.rownum AS rownum,
dat1.id
FROM
test_rnd,
(
SELECT
@rownum := @rownum + 1 AS rownum,
id
FROM
(SELECT @rownum := 0, @last_rownum:=0, @cnt:= 0) AS vars0,
(SELECT id FROM test_rnd ORDER BY wert ASC) AS dat0
) AS dat1
) AS dat2
WHERE
dat2.flag = 1
ORDER BY RAND()
LIMIT 1
Alles mit @sind Variablen. Siehe dazu die MySQL-Doku
Beginne ich ganz innen mit der Erklärung. Ich starte mit 2 SELECT
STEP 1
SUBSELECT dat1:
SQL:
SELECT
@rownum := @rownum + 1 AS rownum,
id
FROM
(SELECT @rownum := 0, @last_rownum:=0, @cnt:= 0) AS vars0,
(SELECT id FROM test_rnd ORDER BY wert ASC) AS dat0
Ausgabe:
Code:
rownum | id
===========
1 | 2
2 | 1
3 | 4
4 | 3
STEP 2
SUBSELECT dat2:
SQL:
SELECT
@cnt := IF(@last_rownum = dat1.rownum, @cnt+1, 0) AS cnt,
(@cnt < dat1.rownum) AS flag,
@last_rownum := dat1.rownum AS rownum,
dat1.id
FROM
test_rnd,
[dat1]
Darum zähle ich für jede ID, wieviel mal sie bereits vorgekommen ist (startend mit 0).
Für jeden Datensatz wird ein Feld ´Flag´ erstellt. Ist dier Counter (@cnt) gleich oder höher der rownum, so wird dieses Flag auf 0 gesetzt. Somit gibt es in unserem Beispiel für id3 4 Datensätze mit Flag 1, für die id4 sind es 3 etc.
Das Resultat sieht dann so aus
Code:
cnt | flag | rownum | id
========================
cnt | flag | rownum | id
========================
0 | 1 | 1 | 2
1 | 0 | 1 | 2
2 | 0 | 1 | 2
3 | 0 | 1 | 2
0 | 1 | 2 | 1
1 | 1 | 2 | 1
2 | 0 | 2 | 1
3 | 0 | 2 | 1
0 | 1 | 3 | 4
1 | 1 | 3 | 4
2 | 1 | 3 | 4
3 | 0 | 3 | 4
0 | 1 | 4 | 3
1 | 1 | 4 | 3
2 | 1 | 4 | 3
3 | 1 | 4 | 3
STEP 3
Zufallszahl und Endfilter
SQL:
SELECT
dat2.id
FROM
[dat2]
WHERE
dat2.flag = 1
ORDER BY RAND()
LIMIT 1
Das ergibt ein Resultat
Code:
id
==
2
1
1
4
4
4
3
3
3
3
Diese Daten nun noch zufällig sortieren und den ersten Wert auslesen....
Zuletzt bearbeitet von einem Moderator: