Temat może brzmi strasznie, ale chodzi (przykładowo) o to, jak wybrać np 3 niepowtarzające się rekordy z bazy danych, losowo, biorąc pod uwagę, że rekord ma pole "ranga" o wartości np od 0 do 3, które ma powodować, że dany rekord ma z większym lub mniejszym prawdopodobieństwem zostać wybrany.
Ogólnie chodzi o wybieranie kilku pozycji z bazy jako promowanych.
Kombinuję jak koń pod górę, podejrzewam, że rozwiązanie jest proste, ktoś wie?
Rozwiązanie może być miksem zapytania SQL i obrobki PHP przed lub po...
pzdr
[PHPSQL] Algorytm losowego wybierania z uwzględnieniem rangi
Re: [PHPSQL] Algorytm losowego wybierania z uwzględnieniem rangi
Kwerenda:
[sql]SELECT * FROM tabela ORDER BY rand()[/sql]
sprawi, że będziesz otrzymywał elementy w losowej kolejności.
Jeżeli dorzucisz LIMIT 1:
[sql]SELECT * FROM tabela ORDER BY rand() LIMIT 1[/sql]
Otrzymasz jeden losowy element.
Sortowanie odbywa się na podstawie wyniku funkcji rand(), która zwraca losową liczbę z przedziału [0,1]. Zwrócony element będzie tym, dla którego wylosowano najmniejszą wartość
Należy zauważyć, że wszystkie elementy są losowane z równym prawdopodobieństwem.
Jak zrobić aby pewne elementy były losowane częściej?
Załóżmy, że masz w tabeli kolumnę ranga która przyjmuje wartości dodatnie (1 lub większe). Jeżeli będziemy losowali elementy na podstawie nie samego rand lecz rand()/ranga to częściej losowane będą elementy z większą rangą. Dzieje się tak ponieważ wylosowane wartości po podzieleniu przez rangę będą mniejsze niż przed podzieleniem.
Czyli ostateczna kwerenda wygląda następująco:
[sql]SELECT * FROM tabela ORDER BY rand()/ranga LIMIT 1[/sql]
O ile częściej będą losowane? W tym celu należy policzyć odpowiednie prawdopodobieństwa (wiąże się z policzeniem całek). Jeżeli jest ci to potrzebne to służę pomocą.
Innym rozwiązaniem może być na przykład losowanie elementu tak:
[sql]ORDER BY rand()-ranga[/sql]
W powyższym przypadku ranga powinna być liczbą z przedziału [0,1]. Im bliższa będzie ona jedynki tym większe prawdopodobieństwo wylosowania elementu
[sql]SELECT * FROM tabela ORDER BY rand()[/sql]
sprawi, że będziesz otrzymywał elementy w losowej kolejności.
Jeżeli dorzucisz LIMIT 1:
[sql]SELECT * FROM tabela ORDER BY rand() LIMIT 1[/sql]
Otrzymasz jeden losowy element.
Sortowanie odbywa się na podstawie wyniku funkcji rand(), która zwraca losową liczbę z przedziału [0,1]. Zwrócony element będzie tym, dla którego wylosowano najmniejszą wartość
Należy zauważyć, że wszystkie elementy są losowane z równym prawdopodobieństwem.
Jak zrobić aby pewne elementy były losowane częściej?
Załóżmy, że masz w tabeli kolumnę ranga która przyjmuje wartości dodatnie (1 lub większe). Jeżeli będziemy losowali elementy na podstawie nie samego rand lecz rand()/ranga to częściej losowane będą elementy z większą rangą. Dzieje się tak ponieważ wylosowane wartości po podzieleniu przez rangę będą mniejsze niż przed podzieleniem.
Czyli ostateczna kwerenda wygląda następująco:
[sql]SELECT * FROM tabela ORDER BY rand()/ranga LIMIT 1[/sql]
O ile częściej będą losowane? W tym celu należy policzyć odpowiednie prawdopodobieństwa (wiąże się z policzeniem całek). Jeżeli jest ci to potrzebne to służę pomocą.
Innym rozwiązaniem może być na przykład losowanie elementu tak:
[sql]ORDER BY rand()-ranga[/sql]
W powyższym przypadku ranga powinna być liczbą z przedziału [0,1]. Im bliższa będzie ona jedynki tym większe prawdopodobieństwo wylosowania elementu
Re: [PHPSQL] Algorytm losowego wybierania z uwzględnieniem rangi
Hej, Cotter
to faktycznie działa, aczkolwiek przyznam, ze bardzo mnie dziwi ta skladnia ORDER BY rand(). Całek nie potrzebuje liczyć, na szczescie poradzilbym sobie z tym w razie czego, dzieki za chęci.
Pytanie tylko jeszcze jedno - to losowanie działa poprawnie, gdy limituje do 1 wyniku. Gdy dam limit 2 albo wiecej, rozklad sie psuje. To nie jest priorytet, ale jesli mialbys jakis pomysl, byłbym wdzięczny i dźwięczny.
Pzdr
Tmz
to faktycznie działa, aczkolwiek przyznam, ze bardzo mnie dziwi ta skladnia ORDER BY rand(). Całek nie potrzebuje liczyć, na szczescie poradzilbym sobie z tym w razie czego, dzieki za chęci.
Pytanie tylko jeszcze jedno - to losowanie działa poprawnie, gdy limituje do 1 wyniku. Gdy dam limit 2 albo wiecej, rozklad sie psuje. To nie jest priorytet, ale jesli mialbys jakis pomysl, byłbym wdzięczny i dźwięczny.
Pzdr
Tmz
Re: [PHPSQL] Algorytm losowego wybierania z uwzględnieniem rangi
Co masz na myśli mówiąc, że rozkład się psuje?
LIMIT 2 zwróci dwa elementy, dla których wylosowano dwie najmniejsze wartości
LIMIT 2 zwróci dwa elementy, dla których wylosowano dwie najmniejsze wartości
Re: [PHPSQL] Algorytm losowego wybierania z uwzględnieniem rangi
Sorewicz, faktycznie jest ok, powtorzylem testy i wychodzi OK.
Dzieki za pomoc, Cotter:)
Dzieki za pomoc, Cotter:)
