| Autor |
Nachricht |
neoexpert
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.11.2005
Beiträge: 579
|
neoexpert Mitglied
15:28:36 28.08.2010 Titel: |
Zufälligen Datensatz selektieren |
Zitieren |
Hallo!
mit
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
kann ich einen zufälligen Datensatz auswählen.
Nun habe ich der Tabelle eine int-Spalte hinzugefügt. Da wird eine zahl abgespeichert. Mit dieser zahl möchte ich die wahrscheinlichkeit, dass ein datensatz ausgewählt wird erhöhen. Also je höher die zahl desto wahrscheinlicher.
Nun kann ich entweder eine Tabelle generieren die jeden datensatz so oft enthält wie in meiner int-Spalte angegeben oder in meiner sql anweisung irgendwie eine Virtuelle tabelle generieren und aus ihr die Datensätze selectieren. geht sowas?
Oder allgemeiner: kann man mit select die Zeilen vervielfacht auswählen? |
_________________ Nicht der Mensch bestimmt seine Meinung, sondern seine Umgebung.
volkard
Zuletzt bearbeitet von neoexpert am 15:58:12 28.08.2010, insgesamt 1-mal bearbeitet |
|
 |
Sqwan
Mitglied
Benutzerprofil
Anmeldungsdatum: 08.01.2006
Beiträge: 965
|
Sqwan Mitglied
15:57:12 28.08.2010 Titel: |
|
Zitieren |
Geht sicher, aber ich glaub ich würds einfach über php machen.
Beim einlesen direkt in ein array und die einträge quasi mit deiner int spalte multipizieren. Und dann mit der random funktion von php eins zufällig wählen. |
_________________ "Besser" impliziert "Anders" aber "Anders" impliziert noch lange nicht "Besser"
Die alte Kuh so schnell vergisst, dass sie selbst mal Kalb gewesen ist!
|
|
 |
neoexpert
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.11.2005
Beiträge: 579
|
neoexpert Mitglied
16:01:02 28.08.2010 Titel: |
|
Zitieren |
Ja da muss man aber dann erst die ganze tabelle einlesen und verarbeiten. wird das nicht perfomanter es mit sql zu erledigen? |
_________________ Nicht der Mensch bestimmt seine Meinung, sondern seine Umgebung.
volkard
|
|
 |
Sqwan
Mitglied
Benutzerprofil
Anmeldungsdatum: 08.01.2006
Beiträge: 965
|
Sqwan Mitglied
16:14:13 28.08.2010 Titel: |
|
Zitieren |
Naja dein ausdruck ließt ja eh die ganze spalte.
ORDER BY RAND() gibts doch auch garnicht. ASC oder DESC.
Ich glaube du meinst sowas wie WHERE id = RAND(); oder sowas...
wenn du eine spalte priorität hast kannst vllt iwie sowas machen:
WHERE priority > RAND().
Aus dem gewählten dann noch mal mit id=RAND() eine raussuchen...
Wie genau das geht weiß ich nicht. Denke mal über subselects.
Auch wie man mit RAND() genau arbeitet weiß ich nicht.
Hast du deine zeile mal gestestet? |
_________________ "Besser" impliziert "Anders" aber "Anders" impliziert noch lange nicht "Besser"
Die alte Kuh so schnell vergisst, dass sie selbst mal Kalb gewesen ist!
|
|
 |
witte
Mitglied
Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
|
witte Mitglied
16:35:49 28.08.2010 Titel: |
|
Zitieren |
| Sqwan schrieb: | Naja dein ausdruck liest ja eh die ganze spalte.
ORDER BY RAND() gibts doch auch garnicht. | Viele DBS geben die Möglichkeit nach der Spaltennummer zu sortiern. Also | Code: | | SELECT a,b,c FROM t ORDER BY 2 | |
| Code: | | SELECT a,b,c FROM t ORDER BY 2 | |
| Code: | | SELECT a,b,c FROM t ORDER BY 2 | |
heißt dann nach b zu sortieren. Dadurch entsteht der zufällige Eindruck. Besser wäre sowas wie | Code: | | SELECT * FROM t LIMIT 1 START RAND() | |
| Code: | | SELECT * FROM t LIMIT 1 START RAND() | |
| Code: | | SELECT * FROM t LIMIT 1 START RAND() | |
(Die genaue Syntax ist DBS-spezifisch). Wobei wohl der RND-Wert nicht größer als die Zeilenanzahl sein sollte.
@OP: Wenn Du Zeilen verdoppeln willst könntest du dich mit einem Kreuzprodukt versuchen. Nehmen wir mal an es gibt 10 Prioritäten:
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE mult (v integer);
INSERT INTO mult (1);
INSERT INTO mult (2);
INSERT INTO mult (3);
INSERT INTO mult (4);
INSERT INTO mult (5);
INSERT INTO mult (6);
INSERT INTO mult (7);
INSERT INTO mult (8);
INSERT INTO mult (9);
INSERT INTO mult (10); | |
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE mult (v integer);
INSERT INTO mult (1);
INSERT INTO mult (2);
INSERT INTO mult (3);
INSERT INTO mult (4);
INSERT INTO mult (5);
INSERT INTO mult (6);
INSERT INTO mult (7);
INSERT INTO mult (8);
INSERT INTO mult (9);
INSERT INTO mult (10); | |
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | CREATE TABLE mult (v integer);
INSERT INTO mult (1);
INSERT INTO mult (2);
INSERT INTO mult (3);
INSERT INTO mult (4);
INSERT INTO mult (5);
INSERT INTO mult (6);
INSERT INTO mult (7);
INSERT INTO mult (8);
INSERT INTO mult (9);
INSERT INTO mult (10); | |
Deine Tabelle besitzt eine Spalte prioritaet. Dann vllt (ungetestet)
| Code: | | SELECT mytable.* FROM mytable,mult WHERE mult.v <= mytable.prioritaet | |
| Code: | | SELECT mytable.* FROM mytable,mult WHERE mult.v <= mytable.prioritaet | |
| Code: | | SELECT mytable.* FROM mytable,mult WHERE mult.v <= mytable.prioritaet | |
|
|
|
|
 |
-=]xXx[=-
Mitglied
Benutzerprofil
Anmeldungsdatum: 15.04.2003
Beiträge: 456
|
-=]xXx[=- Mitglied
18:08:36 28.08.2010 Titel: |
|
Zitieren |
pseudocode:
| Code: | float i = rand();
query = "select * from tabelle where priorität*"+i+">1 order by rand() limit 1";
| |
| Code: | float i = rand();
query = "select * from tabelle where priorität*"+i+">1 order by rand() limit 1";
| |
| Code: | float i = rand();
query = "select * from tabelle where priorität*"+i+">1 order by rand() limit 1";
| |
mfg
xXx |
_________________ Wer nichts macht, macht auch nichts falsch!
Zuletzt bearbeitet von -=]xXx[=- am 18:08:55 28.08.2010, insgesamt 1-mal bearbeitet |
|
 |
no_code
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.06.2010
Beiträge: 310
|
no_code Mitglied
01:59:53 29.08.2010 Titel: |
|
Zitieren |
ich denk ich würd eher subselects nehmen und dann via LIMIT eine zeile rausziehen
edit: sortieren kann da richtig langsam sein wenn kein index drauf ist und dieser müsste ja dann beim vorherigen beispiel auf alle spalten sein was totaler schrott ist
verwendets doch mal zum testen größere tabellen so ab 500mb dann klappts auch mit dem nachbarn |
Zuletzt bearbeitet von no_code am 02:02:14 29.08.2010, insgesamt 1-mal bearbeitet |
|
 |
MJM
Unregistrierter
|
MJM Unregistrierter
10:48:50 29.08.2010 Titel: |
Re: Zufälligen Datensatz selektieren |
Zitieren |
Hi,
| neoexpert schrieb: | Hallo!
mit
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
| Code: | | SELECT spalte FROM tabelle ORDER BY RAND() | |
kann ich einen zufälligen Datensatz auswählen.
Nun habe ich der Tabelle eine int-Spalte hinzugefügt. Da wird eine zahl abgespeichert. Mit dieser zahl möchte ich die wahrscheinlichkeit, dass ein datensatz ausgewählt wird erhöhen. Also je höher die zahl desto wahrscheinlicher. |
Um wieviel wahrscheinlicher ist es denn, dass eine eine Zeile mit prio = 3 gegenüber eine Zeile mit prio = 1 ausgewählt wird? Dreimal so wahrscheinlich? Und ggü. prio = 2 eineinhalb mal so wahrscheinlich?
Mir schwirren da zwei Ansätze im Kopf rum.
a) Du kannst IMHO über prio*RAND() sortieren
b) Der mathematische Ansatz:
Seien die Prioritäten p_1 bis p_n
Die Wahrscheinlichkeit, dass eine bestimmte Spalte i ausgewählt wird, ist also
p_i / (p_1 + ... + p_n) (diesen Ausdruck definiere ich mal als P_i. Er ist normalisiert ggü. allen Prioritäten)
Eigentlich willst du nun eine Zufallszahl X ziehen, und dann schauen
Wenn 0 <= X < P_1, dann nimm Zeile 1
Wenn P_1 <= X < P_1+P_2, dann nimm Zeile 2
Wenn P_1 + P_2 <= X < P_2, dann nimm Zeile 2
...
Wenn Summe(P_j, j=1..i-1) <= X < Summe(P_j, j=1..i), dann nimm Zeile i
...
Wenn P_(n-1) <= X <= 1, dann nimm Zeile n
Dazu müsstest du dann allerdings eine Stored-Procedure (SP) schreiben, um das ordentlich zu lösen (die müsste, grob gesagt, die Zufallszahl (ZF) berechnen (vor deinem Statement, nicht in der SP, weil du ja nur eine ZF haben willst), und dann 1 zurückgeben, wenn die übergebene Zeile die ausgewählte Zeile ist, ansonsten 0. Ich befürchte, dass würde nicht ohne Subrequests funktionieren, da du in der SP tatsächlich alle Prioritäten brauchst).
Gruß, MJM |
|
|
|
 |
no_code
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.06.2010
Beiträge: 310
|
no_code Mitglied
14:55:03 29.08.2010 Titel: |
|
Zitieren |
sauber löst man das nur mit einer ("denormalisierten" das eher das falsche wort) tabelle...
+-+
|a|
|a|
|b|
+-+
und wieviel öfter zieh ich jetzt a statt b |
Zuletzt bearbeitet von no_code am 14:58:09 29.08.2010, insgesamt 1-mal bearbeitet |
|
 |
neoexpert
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.11.2005
Beiträge: 579
|
neoexpert Mitglied
14:57:16 29.08.2010 Titel: |
|
Zitieren |
ja genau so wollte ich das machen. Kann man irgendwie so eine Tabelle mit SQL basteln? In meiner int-spalte ist dabei die anzahl der gewünschten zeilen gespeichert. |
_________________ Nicht der Mensch bestimmt seine Meinung, sondern seine Umgebung.
volkard
|
|
 |
no_code
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.06.2010
Beiträge: 310
|
no_code Mitglied
15:00:14 29.08.2010 Titel: |
|
Zitieren |
deine int spalte bekommst dann mit nem group by... aber nein so einfach geht das nicht. entweder das script oder eine stored procedure kommt aber auch darauf an wennst häufig deine prioritäten änderst kannst das natürlich vergessen... |
|
|
|
 |
neoexpert
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.11.2005
Beiträge: 579
|
neoexpert Mitglied
15:11:16 29.08.2010 Titel: |
|
Zitieren |
| no_code schrieb: |
+-+
|a|
|a|
|b|
+-+
|
Geht das mit SQL aus einer tabelle
+-+-+
|a|2|
|b|1|
+-+-+
die Zeilen zu vervielfachen? Die zweite spalte ist dabei der Faktor um den vervielfacht wird.
+-+
|a|
|a|
|b|
+-+ |
_________________ Nicht der Mensch bestimmt seine Meinung, sondern seine Umgebung.
volkard
Zuletzt bearbeitet von neoexpert am 15:11:44 29.08.2010, insgesamt 1-mal bearbeitet |
|
 |
no_code
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.06.2010
Beiträge: 310
|
no_code Mitglied
15:16:48 29.08.2010 Titel: |
|
Zitieren |
kommt auf deine datenbank an. ohne stored procedures denke ich nein |
|
|
|
 |
no_code
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.06.2010
Beiträge: 310
|
no_code Mitglied
15:32:48 29.08.2010 Titel: |
|
Zitieren |
statt die ganzen zeilen kannst auch ne 2. tabelle nehmen in der nur die ids für die erste tabelle liegen dann hast auch nicht nen ganz so großen overhead...
so wars gedacht...
+-+-+-+
|1|a|2|
|2|b|1|
+-+-+-+
+-+
|1|
|1|
|2|
+-+
naja viel spaß beim frickeln |
Zuletzt bearbeitet von no_code am 15:34:42 29.08.2010, insgesamt 1-mal bearbeitet |
|
 |