Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: SQL: Satunnainen rivi painotetusti

t0ll0 [18.02.2013 19:37:56]

#

Morjensta,

Eli sivuillani on ajax-koodi mikä hakee tiettyä dataa ("iskulauseita") tietokannasta tietyin väliajoin ja homma toimii siltä osin kyllä, mutta haluaisin tietyille riveille suuremman "painoarvon" eli todennäköisyyden tulla esitetyksi.

En ole vielä mitään toteuttanut sen suhteen muutakuin suunnitelmia ja ainoa tapa mikä minulle tulee mieleen on kaksi eri taulua tyyliin:

Taulu Data
id - data
1 - data1
2 - data2
3 - data3

Taulu Painoarvo
id - data_id
1 - 1
2 - 1
3 - 2
4 - 3

Ja haetaan data_id satunnaiselta riviltä taulusta Painoarvo mikä esitetään. Yllä mainituilla tauluilla on siis todennäköisempää että data1 tulee esitetyksi kuin muut.

Onko mahdollista toteuttaa samat "todennäköisyydet" yhdellä taululla tyyliin:

Taulu Data
id - data - painoarvo
1 - data1 - 2
2 - data2 - 1
3 - data3 - 1

Vai mikä tässä olisi parhain ratkaisu? Homma toimii tosiaan jo nykyisellään, että tämä on pelkkää hifistelyä. Aloin kuitenkin moista suunnittelemaan ja jo pelkästään mielenkiinnosta kysyn onko tämmöiseen minkälaisia ratkaisuja olemassa.

Metabolix [18.02.2013 22:33:57]

#

Kyllä painottaminen suoraan luvuillakin on mahdollista. Ilman painotusta rivit voi vain järjestää satunnaisluvun mukaan. Kun painoarvot vaihtelevat, satunnaisluvusta pitää ottaa juuri painoarvolla eli satunnaisluku pitää korottaa potenssiin 1/painoarvo. Kaavan voi pyöräyttää myös logaritmimuotoon. Toisin kuin painottamattomassa tapauksessa, nyt myös järjestyksen suunta on tärkeä.

SELECT * FROM taulu ORDER BY POW(RAND(), 1 / painoarvo) DESC LIMIT 1;
SELECT * FROM taulu ORDER BY LOG(RAND()) / painoarvo DESC LIMIT 1;

Toinen tapa päästä vastaavaan tulokseen on arpoa ensin luku $X väliltä nollasta yhteen (PHP:ssä esim. lcg_value()) ja tehdä sitten tällainen kysely:

SELECT * FROM taulu AS t1 WHERE
	(SELECT SUM(painoarvo) FROM taulu AS t2 WHERE t2.id <= t1.id)
	>= $X * (SELECT SUM(painoarvo) FROM taulu)
ORDER BY id ASC LIMIT 1

Kyselyssä otetaan siis id:n mukaan ensimmäinen rivi, jolla painoarvojen summa kyseiseen riviin mennessä (ensimmäinen alikysely) on vähintään sama kuin satunnainen osuus painoarvojen kokonaissummasta ($X * toinen alikysely).

t0ll0 [19.02.2013 11:32:30]

#

Noniin noihan toimii hienosti! Kiitos..

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta