[MySQL/PHP] SELECT ... ORDER BY RAND() Lösungen gesucht *erledigt*

strolch00

redraft.de
ID: 155297
L
21 April 2006
1.684
72
Hi @all,

ich habe auf meiner Seite eine DB Anfrage der Mitglieder welche mit RAND() die Mitglieder ausliefert. Jetzt habe ich aber das Problem das mit der Blätterfunktion und dem ORDER BY RAND() das ganze nicht hinhaut so wie gedacht(eigentlich logisch).
Nun brauche ich eine Idee um die Mifglieder per Rand auszulesen aber auch keine mitglieder auf den folgeseiten doppelt angezeigt zu bekommen.

Ich habe mir auch schon überlegt das ganze nur einmal abzufragen und in einem Array aufzufangen, allerdings habe ich dann auch wieder das Problem dasich den Shuffle nicht immer gleich hinbekomme, um die folge Schlüssel zu holen.

Hat jemand eine Idee wie man sowas lösen könnte? Ich steh in der Hinsicht mal echt auf dem Schlauch.
 
Zuletzt bearbeitet:
Kommt halt drauf an, wie oft die "Randomisierung" durchgeführt werden soll.

Ich würde das einfach lösen und zwar mit einer zusätzlichen FLOAT-Spalte (kann man auch INT nehmen und dann unten die Formel mit Multiplikation erweitern), die die "zufälligen" IDs enthält.

Bei jeder Änderung der Usertabelle (neues Mitglied, Mitglied löschen) das ausführen:
Code:
[FONT=Courier New][B][COLOR=#9932cc]UPDATE[/COLOR][/B] `users`
[B][COLOR=#9932cc]SET[/COLOR][/B] `random_id` = [B][COLOR=#9932cc]RAND[/COLOR][/B][COLOR=#9932cc]([/COLOR][COLOR=#9932cc])[/COLOR][/FONT]
Beim Auslesen einfach so:
Code:
[FONT=Courier New][B][COLOR=#9932cc]SELECT[/COLOR][/B] `field1`,`field2`
[B][COLOR=#9932cc]FROM[/COLOR][/B] `users`
[B][COLOR=#9932cc]ORDER[/COLOR][/B] [B][COLOR=#9932cc]BY[/COLOR][/B] `random_id` [B][COLOR=#9932cc]ASC[/COLOR][/B]
[B][COLOR=#9932cc]LIMIT[/COLOR][/B] 60,30[/FONT]
So bleibt auch beim Blättern die Reihenfolge erhalten.

Ein PHP-Array bringt nicht wirklich was, weil du das ja auch abspeichern müsstest und das wäre viel zu kompliziert.
Einfach eine zweite ID-Spalte anlegen.
 
Hi danke euch beiden jedoch bringt mich das net ganz ans Ziel.

Ich möchte das jeder User das anders sieht also kein User sollte das gleiche Rand haben. Ich weis leider net wie ich es anders ausdrücken soll.

Ichversuch es mal an einem beispiel, erst dachte ich die Lösung von theHacker ist es gefällt mir auch ganz gut, allerdings habe ich es so gelöst
PHP:
if(!isset($_SESSION['team_rand']))
	$DbCl->_Query("UPDATE `".$Table['team_redraft']."` SET `RandID` = RAND()");
	if($DbCl->_AffRow())
		$_SESSION['team_rand'] = time();
,weil ich ja für jeden User eine andere Rand haben wollte. Nun ist es aber so wenn zwei User drin sind wird das RAND() zweimal gesetzt, somit ist meine Blätterfunktion und die unterschiedlichen Ansichten dahin.

Genauso ist es mit einer Temporären Tabelle könnte ich machen allerdings muss ich die immer nach einer bestimmten Zeit per Cron wieder löschen lassen.

Aber wenn ich beides erfüllen will, also jeder User andere Ansicht und blätterfunktions so wie es sein soll. Bleibt mir eigentlich nur die Platzsparendste Lösung einer RAND-Tabelle mit UserID TeamID RandID Time wobei UserID der primarie key ist wo die einzelnen Userids drinstehen. Und mit deren hilfe ich joinen kann. Oder seht ihr andere Lösungen?
 
welchen Sinn soll es überhaupt haben die Mitglieder randomisiert auszulesen für jeden Benutzer anders?
Aber temporäre Tabellen wären die eigentliche Lösung, ob das nur Referenzen auf die einzelnen Datensätze sind ist ja egal.
 
Also, so wie ich das sehe gibt es außer den temporären Tabellen keine wirklich sinnvolle Möglichkeit, dass jeder User seine eigene Reihenfolge angezeigt kriegt.

Zumindestens nicht mit den mitteln von PHP und MySQL.
Was du allerdings probieren könntest:

Lese die ganze Tabelle mit RAND() aus, und lass die von PHP wieder so ausgeben, dass du ein JS-Array erstellst. Dann musst du nur meim Laden der Seite (<body onload="blabla();">) eine Javascript funktion aufruft, die die Tabelle wahlweise erst dynamisch generiert (sehr schön, wenn man dann auch die Anzahl der Zeilen etc. dynamisch gestalten kann) oder eine bereits existierende Tabelle (php-Ausgabe) dynamisch füllt (afaik wesentlich einfacher).

Sicherlich kann man damit eine sehr schön gestaltete Tabelle erreichen, und es würde deinen Wunsch erfüllen. Allerdings solltest du bei JS immer darauf achten, dass verschiedene Browser da verschiedene Ansichten haben, wenn es um die Umsetzung von Anweisungen geht. Außerdem gibt es regelmäßig User, die kein JS aktiviert haben, auch die hätten Probleme.

Anmerkung: Weiß grad nicht, in wie weit meine Erinnerung mich täuscht, aber obwohl ich meine, dass JS und JavaScript geringfügig verschieden sind, ist mein Text auf beides bezogen ;-)
 
Ja aber das ist alles zu umständlich, außerdem bild ich mir ein das es in XHTML 1.1 kein document.write mehr geht. (kann mich auch täuschen)

Wenn ich eine tmp Tabelle anlegen dann müsste ich das für jede UserID machen wegen den verschiedenen Ansichten. und dort kommen wir zu doppelten Datensätzen. Dann lieber theHackers lösung mit nur einer Spale mehr, dann muss ich halt damit leben das jeder user die gleiche Ansicht hat.
Dachte nur es ginge vielleicht den rand wert irgendwie zu speichern, so das man immer den selben random wert erhält oder man kann mit cookies was treiben.
 
spez. thx @claudi

hier unsere Lösung:

mit folgendem Code den Startwert für den Zufallsgenerator initialisieren
PHP:
// RandomID setzen wenn noch nicht geschehen --------------
if(!isset($_SESSION['rand_seed']))
	$_SESSION['rand_seed'] = (double)microtime() * 1000000;		// seed with microseconds since last "whole" second
srand($_SESSION['rand_seed']);
// --------------------------------------------------------

somit kann man ohne ein Rand im Query alles nacheinander abfragen und dann per shuffle(ARRAY); immer gleich randomizen lassen. Für jeden User anders und mit der Blätterfunktion gibts auch keine Probleme.

:mrgreen: Was für ein Kraftakt um diese unmenschliche Zeit.
 
Zuletzt bearbeitet:
ich weiß nicht wieviele einträge es sind, aber man könnte ja auch die sortierung in einem cookie/einer session speichern und dann bei den einzelnen seiten nachsehen welche datensätze man alden muss (2 dimensionales array)
 
Wenn ich in $_SESSION[] einen Zufallscode habe, kann ich damit doch noch keine doppelten IDs ausschließen ?
In der Session wird nur der Startwert für den Pseudo-Zufallsgenerator gespeichert.

Und wir alle wissen: selber Startwert, selbe "Zufalls"zahlen, selbe Sortierreihefolge.
D.h. mit demselben Startwert kannst du die Liste immer gleich "zufällig" sortieren lassen, sodass ein User immer dieselbe Reihenfolge kriegt, die aber für ihn trotzdem zufällig ist.
 
In der Session wird nur der Startwert für den Pseudo-Zufallsgenerator gespeichert.

Und wir alle wissen: selber Startwert, selbe "Zufalls"zahlen, selbe Sortierreihefolge.
D.h. mit demselben Startwert kannst du die Liste immer gleich "zufällig" sortieren lassen, sodass ein User immer dieselbe Reihenfolge kriegt, die aber für ihn trotzdem zufällig ist.

:wall: stimmt, ich glaub ich geh besser wieder schlafen ...
 
Guten morgen :yawn:

jop genau richtig ich speichere für jeden User beim ersten aufruf der Seite einen startwert in der Session, undsomit lass ich jedesmal die Teammitglieder in einen Array speichern, den ich dann mit shuffle für jeden einzelnen User unterschiedlich aber immer gleich sortieren kann. Der rest wird nur mit einer for schleife durchlaufen.

hier mal der Code in Groben Zügen

PHP:
// RandomID setzen wenn noch nicht geschehen --------------
if(!isset($_SESSION['rand_seed']))
	$_SESSION['rand_seed'] = (double)microtime() * 1000000;		// seed with microseconds since last "whole" second
srand($_SESSION['rand_seed']);
// --------------------------------------------------------

/*
 * Query
 */

$res = $DbCl->_Query($sql);

	if($anzahl = mysql_num_rows($res))
	{
		$Team = array();
		while($erg = mysql_fetch_assoc($res))
			$Team[] = $erg;  //Array füllen

		shuffle($Team);		// Array mixen

		$Team_output = array();
		for ($x = $min; $x < ($min + ZAHLER); $x++)
		{
			if(!isset($Team[$x]))		// wenn Array leer aufhören
				break;

			/*
			 * TPL Aktionen
			 * $Team_output wird gefüllt
			 */
		}


		// Blätterfunktion ----------------------------------
		$seite = 1;
		$Seiten = '';
		while(ceil($anzahl / ZAHLER) >= $seite)		// Seitenanzahlausgabe --------
		{
			if(ceil($anzahl / ZAHLER) == 1)		// abbrechen wenn es nur eine ist
				break;

			$Seiten .= "[<a href=\"/team:".$_GET['kat'].",S".$seite."\">".$seite."</a>]";
			$seite ++;
		}
		// --------------------------------------------------

		$CTpl->SetLoop('LOOP', $Team_output);		//LOOP AUSGABE

Ist ein bisschen komisch von der einrückung her weil es nur das nötigste ist.
 
Zuletzt bearbeitet: