Atsitiktinio įrašo suradimas su ActiveRecord
- Posted on May 13th, 2007 filed in Ruby on Rails, Snippets
- 5 Comments »
Norint surasti atsitiktinį įrašą MySQL'e naudojame
[code]
SELECT * FROM products ORDER BY rand();
[/code]
Norint tą gražiai atlikti su ActiveRecord galime panaudoti
[code]
Product.find(:all, :order => ‘rand()’)
[/code]
Update: tas pats, bet PostgreSQL'ui
[code]
Product.find(:all, :order => ‘random()’)
[/code]
May 14th, 2007 at 08:12
Hmm, “ORDER BY rand()” labai neracionalus sprendimas, įvertinant tai, kad atsitiktinio sk. generavimas yra “brangi” operacija, o tokių operacijų generuojama kiekvienai eilutei…
May 14th, 2007 at 22:44
Atsizvelgiant i Lucy komentarus, del optimalumo, galime patobulinti kreipimasi: “Product.find(:all, :order => ‘rand()’, :limit => 10)”. Tokiu atveju rand’as veiks tik ant siu eiluciu. Ir avis sveika ir vilkas sotus :)
May 15th, 2007 at 09:50
Ačiū už komentarus. Iš tikrųjų tai kodas ir naudoja limit’ą, kadangi reikia parodyti tik keletą random item’ų, o ne visus =)
August 29th, 2007 at 16:30
Kiek pamenu tokie dalykai didelėms lentelėms užstabdytų…
Reikėtų pasitestuoti su dideliu duomenų kiekiu/didele apkrova.
Alternatyvūs variantai:
- išsitraukti visus ID ir random() atlikti programavimo kalboje.
- SELECT id FROM products ORDER BY rand(); ir po to SELECT * FROM products WHERE id=ID;
Beje, skirtingas kodas MySQL ir PostgreSQL — labai neelegantiška.
March 2nd, 2010 at 21:12
Jei jau radau aš, gal dar kas ras… :)
SELECT count() as total_cnt FROM A
ir antra užklausa
SELECT * FROM A LIMIT rand (0, total_cnt), 1
t.y. pirma gaunam, kiek viso įrašų yra, aks yra labai greita su index’ais, tada išrenkam vieną vienintelę eilutę paprastu selectu, kas vėlgi labai greita ;)