Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Satunnaisen painotetun rivin hakeminen kannasta

AkeMake [05.09.2011 19:40:10]

#

Jostain syystä en millään keksi miten saan tietokannasta haettua satunnaisen rivin, kun jokaisen rivin esiintymistodennäköisyyttä painotetaan kentässä määrätyn luvun verran.

On siis taulu, joka sisältää kentät id, productid, importance ja published. Tästä taulusta pitäisi hakea yksi satunnainen julkaistu rivi.
Jos taulussa on esimerkiksi neljä riviä joiden importance-kenttien arvot ovat 1, 5, 7 ja 2, mutta näistä kolmannella rivillä on published=0, ensimmäinen rivi valittaisiin 1/8, toinen 5/8 ja neljäs 2/8 todennäköisyydellä. Kolmatta riviä ei luonnollisesti valittaisi.

Minulla on jonkinlaista hämärää kuvaa siitä miten tuo voitaisiin suunnilleen toteuttaa, mutta se lopullinen ratkaisu puuttuu. En saa ajatuksiani siirrettyä järkevässä muodossa koneelle toimivaksi kyselyksi. :P

Metabolix [08.09.2011 16:29:35]

#

Seuraava kysely taitaisi toimia:

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

Tässä $X on etukäteen generoitu satunnaisluku (0–1) esim. funktiolta lcg_value().

Vaikka kyselystä tuli tosi hieno, luultavasti on tehokkaampaa tehdä pari yksinkertaisempaa kyselyä ja keskittää laskut PHP:n puolelle.

$painot = sql("SELECT paino, COUNT(*) FROM taulu GROUP BY paino");
// $painot = array(paino => COUNT(*))

$painosumma = 0;
foreach ($painot as $paino => $maara) {
  $painosumma += $maara * $paino;
}

$n = mt_rand(0, $painosumma - 1);
foreach ($painot as $paino => $maara) {
  $n -= $maara * $paino;
  if ($n < 0) {
    break;
  }
}

$n = mt_rand(0, $painot[$paino] - 1);
$rivi = sql("SELECT * FROM taulu WHERE paino = $paino ORDER BY id LIMIT 1 OFFSET $n");

(Lisää itse kaikkiin kyselyihin ja alikyselyihin WHERE published = 1.)

AkeMake [09.09.2011 22:16:48]

#

Kiitos. Tuo kysely on sen verran hieno, etten ymmärtänyt siitä paljoakaan. Taidan tosiaan tehdä tämän PHP:llä, jos se on tehokkaampikin. Jonkin aikaa pohdittuani ymmärsin myös miksi tästä antamastasi PHP-pätkästä saa ulos vaatimani ehdot täyttävän tuloksen.

Vastaus

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

Tietoa sivustosta