Problem mit SQL-Abfrage

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Benutzeravatar
atrox
Mitglied
Beiträge: 242
Registriert: 08.08.2007 00:48
Wohnort: Ravensburg

Beitrag von atrox »

. Ich möchte es aber zwar gern so, dass z.B. der Vorname per Zufall ausgelesen wird. Nur sollen die anderen Informationen aus der gleiche Zeile stammen. Wie mache ich das?

Code: Alles auswählen

SELECT `user_regdate` FROM `phpbb3_users` WHERE `username` = (SELECT `username` FROM `phpbb3_users` WHERE `user_id` = CEILING(RAND() * (SELECT COUNT(*) FROM `phpbb3_users`)) LIMIT 1);
Wäre die ganz genaue Umsetzung der Fragestellung, leider ist bei dieser MySQL Anforderung die Serverlast enorm (mein Heimrechner benötigt ohne besondere Belastungen mehr als 5sek mit 3,2GHz und 1,5GB Arbeitsspeicher).

Sofortlösung

Code: Alles auswählen

SELECT * FROM `phpbb3_users` WHERE `user_id` = CEILING(RAND() * (SELECT COUNT(*) FROM `phpbb3_users`)) LIMIT 1;

-----------------------------------------
Ich nehme mir hier die Freiheit und beschreibe die Abfrage, damit du sie nach deinen eigenen Vorstellungen gestalten kannst.
Ich habe die Erklärung extra so verfasst, dass man dem Code 1 zu 1 folgen kann.
Eines Vorweg, man kann mehrere Informationen in einer Abfrage abfragen, indem man Klammern setzt (der MySQL Interpreter kommt dadurch auch nicht durcheinander).
Vom dem Gedankengang ist es wie eine Rechnung.

Code: Alles auswählen

$i = 4 * (3+2);
$i = 4 * 5;
$i = 20;
Wähle das Feld `user_regdate` (oder irgendein anderes beliebiges) aus der Tabelle `phpbb3_users` anhand des Usernames (Feld `username`).
Dieser wird ausgewählt anhand des Feldes `user_id`.
Dieses wiederum wird durch einen Zufallswert (RAND()) mal der maximalen Datensatzmenge (Zähle alle Datensätze aller Felder aus der Tabelle ==> (SELECT COUNT(*) FROM `phpbb3_users`)). Runde das Ergebnis (CEILING(...)), damit eine schöne ganze Zahl (bzw. ID) übergeben werden kann.

Durch die Rundung (und die Anzahl der Datensätze) bekommt man eine ID, mit der man einen Usernamen bestimmen kann und mit diesem kann man die restlichen Felder bestimmen.
-----------------------------------------


Besser wäre es also alle benötigten Informationen in einer Abfrage (ohne Verschachtelung) unter zu bringen.
Also etwa so.

Code: Alles auswählen

SELECT * FROM `phpbb3_users` WHERE `user_id` = CEILING(RAND() * (SELECT COUNT(*) FROM `phpbb3_users`)) LIMIT 1;
Diese Methode hat allerdings einen Nachteil, wenn eine Zahl gewürfelt wird die nicht vorkommt (weil vielleicht der Datensatz gelöscht wurde) gibt es keine Ausgabe (dies gilt auch für den ersten Lösungsvorschlag).


Um immer ein Ergebnis zu bekommen, ist es sinnvoll eine eigene (Random-)Spalte anzulegen und diese mit zufälligen Werten zu füllen (ein Zufallswert pro Datensatz).
(Random-)Spalte füllen:

Code: Alles auswählen

UPDATE `phpbb3_users` SET `random` = RAND();
Felder auslesen:

Code: Alles auswählen

SELECT * FROM `phpbb3_users` WHERE `random` > RAND() ORDER BY `random` LIMIT 1
Da mehrer Datensätze ausgeliefert werden und alles zufallsbestimmt sein soll (soweit möglich), sollte das ganze anhand der Spalte selbst sortiert werden.
Allerdings muss ab nun die Randomspalte immer mit gefüllt werden (da sonst immer aus den gleichen Gewählt wird).

Gruß atrox
Benutzeravatar
porfavor
Mitglied
Beiträge: 834
Registriert: 23.08.2006 00:35
Wohnort: Tuttlingen
Kontaktdaten:

Beitrag von porfavor »

Ohje jetzt hast du dir solche Mühe gemacht und es bringt mir nicht sehr viel.

Das hat alles gar nichts mit phpBB zu tun. Es ist ein eigenes Script.
Das hier ist für einen Newbie dann doch verwirrend.
Ich brauche das ganze auch nicht in der gleichen Datei, ist nun anders. Es geht nur um das Auslesen.

Mal der Code

Code: Alles auswählen



<?php



/*Verbindung zur DB*/
include_once("db.php");




/*Per Zufall aus der DB auslesen*/

$abfrage1 = mysql_query("Select firstname FROM hug ORDER BY RAND() LIMIT 1");
 $resfirstname1 = mysql_fetch_assoc($abfrage1);
 foreach ($resfirstname1 as $resfirstname) {}
 $abfrage2 = mysql_query("Select surname FROM hug ORDER BY RAND() LIMIT 1");
 $ressurname1 = mysql_fetch_assoc($abfrage2);
 foreach ($ressurname1 as $ressurname) {}
 $abfrage3 = mysql_query("Select gender FROM hug ORDER BY RAND() LIMIT 1");
 $resgender1 = mysql_fetch_assoc($abfrage3);
 foreach ($resgender1 as $resgender) {}
 $abfrage4 = mysql_query("Select day FROM hug ORDER BY RAND() LIMIT 1");
 $resday1 = mysql_fetch_assoc($abfrage4);
 foreach ($resday1 as $resday) {}
 $abfrage5 = mysql_query("Select month FROM hug ORDER BY RAND() LIMIT 1");
 $resmonth1 = mysql_fetch_assoc($abfrage5);
 foreach ($resmonth1 as $resmonth) {}
 $abfrage6 = mysql_query("Select year FROM hug ORDER BY RAND() LIMIT 1");
 $resyear1 = mysql_fetch_assoc($abfrage6);
 foreach ($resyear1 as $resyear) {}
 $abfrage7 = mysql_query("Select state FROM hug ORDER BY RAND() LIMIT 1");
 $resstate1 = mysql_fetch_assoc($abfrage7);
 foreach ($resstate1 as $resstate) {}
 $abfrage8 = mysql_query("Select location FROM hug ORDER BY RAND() LIMIT 1");
 $reslocation1 = mysql_fetch_assoc($abfrage8);
 foreach ($reslocation1 as $reslocation) {}
 $abfrage9 = mysql_query("Select email FROM hug ORDER BY RAND() LIMIT 1");
 $resemail1 = mysql_fetch_assoc($abfrage9);
 foreach ($resemail1 as $resemail) {}
 $abfrage10 = mysql_query("Select comment FROM hug ORDER BY RAND() LIMIT 1");
 $rescomment1 = mysql_fetch_assoc($abfrage10);
 foreach ($rescomment1 as $rescomment) {}
mysql_close($connect);

// Klasse hinzuladen
include("template.class.php");

// Objekt erzeugen ($error wird bereits im Konstrukt definiert und ist hier nur optional)
$template = new template("result.html");
// Datei einlesen
$template->readtemplate();
// Platzhalter ersetzen

$template->replace("FIRSTNAME", $resfirstname);
$template->replace("SURNAME", $ressurname);
$template->replace("GENDER", $resgender);
$template->replace("DAY", $resday);
$template->replace("MONTH", $resmonth);
$template->replace("YEAR", $resyear);
$template->replace("STATE", $resstate);
$template->replace("LOCATION", $reslocation);
$template->replace("EMAIL", $resemail);
$template->replace("COMMENT", $rescomment);

// Seite ausgeben
$template->parse();


?>

Vielleicht wird mein Problem jetzt klarer.

Meine Frage wäre eher, ob oder wie es möglich ist, eine Abfrage also einen SELECT * auszuführen (wenn ich dann rand nehm wird ja eine ganze Zeile zufällig gewählt?) und dann die verschiedenen Resultate also die verschiedenen Spalten in einzelne Variablen zu packen

Also so nach dem motto: (keine syntax, nur prinzip)
SELECT * from tabelle order by rand()
aber mehrere variablen für die verschiedenen ergebnisse aus * zu haben.

Danke für die Hilfe. Ich werde schauen, ob ich morgen etwas aus deinem Post schließen kann. Ist jetzt zu spät.
Lebe dein Leben solange du kannst.

Jugendgemeinderat-Tuttlingen
Benutzeravatar
atrox
Mitglied
Beiträge: 242
Registriert: 08.08.2007 00:48
Wohnort: Ravensburg

Beitrag von atrox »

Das hat alles gar nichts mit phpBB zu tun. Es ist ein eigenes Script.
Ich hab die MySQL Befehle Allgemein beschrieben, dabei hab ich die Tabellennamen nur als Beispiel genommen.
SELECT * from tabelle order by rand()
SELECT * FROM tabelle WHERE feld = RAND() // <-- So isses eig gemeint

Code: Alles auswählen

$abfrage1 = mysql_query("Select firstname FROM hug ORDER BY RAND() LIMIT 1");
 $resfirstname1 = mysql_fetch_assoc($abfrage1);
[...]
Uff, lass das doch die Maschine machen.

Ich schreib Morgen mehr dazu :wink:
Benutzeravatar
porfavor
Mitglied
Beiträge: 834
Registriert: 23.08.2006 00:35
Wohnort: Tuttlingen
Kontaktdaten:

Beitrag von porfavor »

ja wie gesagt, ich bin total unerfahren in sql und hab mir das noch nicht alles angeschaut. Ja mit where muss das wenn irgendwie gehen...

Aber ich will kein Zufälliges Feld auslesen sondern eine zufällige Zeile. Es sollen alle Felder einer zufälligen Zeile ausgelesen werden.
Lebe dein Leben solange du kannst.

Jugendgemeinderat-Tuttlingen
Benutzeravatar
atrox
Mitglied
Beiträge: 242
Registriert: 08.08.2007 00:48
Wohnort: Ravensburg

Beitrag von atrox »

Aber ich will kein Zufälliges Feld auslesen sondern eine zufällige Zeile. Es sollen alle Felder einer zufälligen Zeile ausgelesen werden.
Das hab ich ja alles schon in dem großen Post oben beschrieben (im Kasten), hab ich das zu kompliziert geschrieben oder was blickst da net? :D

MySQL Abfragen würd ich grundsätzlich erst im phpMyAdmin ausprobieren, dort hat man alles im Blick und die Ausgabe ist besser.

Gruß atrox
Benutzeravatar
porfavor
Mitglied
Beiträge: 834
Registriert: 23.08.2006 00:35
Wohnort: Tuttlingen
Kontaktdaten:

Beitrag von porfavor »

Ich denke, das mit der Abfrage verstehe ich schon.

Code: Alles auswählen

SELECT * FROM tabelle WHERE feld = RAND()
liest mir eine komplette zufällige Zeile aus, bei der ich das Feld noch bestimmen kann?


Aber was ich ja wissen will ist, wie baue ich das dann in einen php-variable um. Ich kann ja $var= mysql_select...Abfrage schreiben, aber dann hab ich alle Infos in einer Variable.
Sorry, wahrscheinlich sehe ich den Wald vor lauter Bäumen schon nicht mehr. :roll:
Lebe dein Leben solange du kannst.

Jugendgemeinderat-Tuttlingen
Benutzeravatar
atrox
Mitglied
Beiträge: 242
Registriert: 08.08.2007 00:48
Wohnort: Ravensburg

Beitrag von atrox »

[...]aber dann hab ich alle Infos in einer Variable.
Das ist doch toll, dann musst du nur die eine Variable ansprechen.

Code: Alles auswählen

$abfrage = mysql_query("SELECT * FROM hug WHERE int_feld = CEILING(RAND()*(SELECT COUNT(*) FROM hug)");
 $res = mysql_fetch_assoc($abfrage); 


$template->replace("FIRSTNAME", $res['firstname']);
$template->replace("SURNAME", $res['surname']);
$template->replace("GENDER", $res['gender']);
$template->replace("DAY",  $res['day']);
$template->replace("MONTH", $res['month']);
$template->replace("YEAR", $res['year']);
...
In $res sind nun alle Werte, bennant nach ihrem Feldnamen.
Benutzeravatar
porfavor
Mitglied
Beiträge: 834
Registriert: 23.08.2006 00:35
Wohnort: Tuttlingen
Kontaktdaten:

Beitrag von porfavor »

oh danke

Ja das ist dann ja super einfach. Da hätten wir es nicht so kompliziert gebraucht :D

Edit: also mit deiner abfrage kriege ich einen Fehler wegen non-valid mysql...

Nehme ich

Code: Alles auswählen

$abfrage = mysql_query("Select * FROM hug ORDER BY RAND() LIMIT 1");
 $res1 = mysql_fetch_assoc($abfrage);
 foreach ($res1 as $res) {}
Gibt es mir immer nur einen Buchstaben jeweils aus. Und zwar einen zufälligen habe ich das gefühl.
Lebe dein Leben solange du kannst.

Jugendgemeinderat-Tuttlingen
Benutzeravatar
atrox
Mitglied
Beiträge: 242
Registriert: 08.08.2007 00:48
Wohnort: Ravensburg

Beitrag von atrox »

Stimmt, ich hab die letzte Klammer nicht geschlossen.

Code: Alles auswählen

$abfrage = mysql_query("SELECT * FROM hug WHERE int_feld = CEILING(RAND()*(SELECT COUNT(*) FROM hug)) LIMIT 1"); 
So müsste es gehen, das int_feld ist natürlich nur Platzhalter für ein anderes Nummerischesfeld (da RAND() nur Zahlen zurückgibt).
Benutzeravatar
porfavor
Mitglied
Beiträge: 834
Registriert: 23.08.2006 00:35
Wohnort: Tuttlingen
Kontaktdaten:

Beitrag von porfavor »

Ach rand() gibt nur Zahlen zurück?

Ok
habe es mit dem Feld "day" gemacht.

Dankeschön! :)

Jetzt sollte ich alleine weiterkommen.

Edit:

Doch noch was: Nach mehrmaligem Reload kommt ab und zu keine ausgabe. Hängt das mit Limit zusammen?
Lebe dein Leben solange du kannst.

Jugendgemeinderat-Tuttlingen
Antworten

Zurück zu „Coding & Technik“