Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Datenbanken ::  Zufälligen Datensatz selektieren     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
neoexpert
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.11.2005
Beiträge: 579
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag -=]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
Beitrag 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 :die:

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




Beitrag 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
Beitrag 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 :confused:


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
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag 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 :D


Zuletzt bearbeitet von no_code am 15:34:42 29.08.2010, insgesamt 1-mal bearbeitet
C/C++ Forum :: Datenbanken ::  Zufälligen Datensatz selektieren   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.