sql - mysql weighted random results - how to get changed variable value after SELECT -
i have table keywords
columns keyword
, weight
. goal randomly select 1 keyword
, regard weight
(probability). found 2 ways solve this, latter 1 more elegant (and consumes less ressources) - dont run. see yourself.
the table , records:
create table if not exists `keywords` ( `keyword` varchar(100) collate utf8_bin not null, `weight` int(11) not null, unique key `keywords` (`keyword`), key `rate` (`weight`) ) engine=myisam default charset=utf8 collate=utf8_bin; insert `keywords` (`keyword`, `weight`) values ('google', 50), ('microsoft', 20), ('apple', 10), ('yahoo', 5), ('bing', 5), ('xing', 5), ('cool', 5);
query 1
consumes more ressources, work on 5k+ records. source why mysql query using rand() return no results third of time?:
select * `keywords` order -log(1.0 - rand()) / weight limit 1
query 2
sums weights @weight_sum
. sets @weight_point
rand()
number within range. loops through records, substracting weight
@weight_pos
, setting @keyword
current keywords.keyword
. until @weight_pos < 0
. keeps keyword
. source random weighted choice in t-sql
set @keyword = 0; set @weight_sum = (select sum(weight) keywords); set @rand = rand(); set @weight_point = round(((@weight_sum - 1) * @rand + 1), 0); set @weight_pos = @weight_point; select keyword, weight, @keyword:=case when @weight_pos < 0 @keyword else keyword end test, (@weight_pos:=(@weight_pos - weight)) curr_weight, @weight_point, @keyword, @weight_pos, @rand, @weight_sum keywords;
see phpmyadmin results here http://postimg.org/image/stgpd776f/
my question
how value in @keyword
, or test
column holds in end? adding select @keyword
afterwards doesn't change anything.
ok, think question more or less basic mysql-question. achieved wanted encapsulating above select statement select, filtered first one's result searched. sorry bothering you. see query:
set @keyword = 0; set @weight_sum = (select sum(weight) keywords); set @rand = rand(); set @weight_point = round(((@weight_sum - 1) * @rand + 1), 0); set @weight_pos = @weight_point; select t.test ( select keyword, weight, @keyword:=case when @weight_pos < 0 @keyword else keyword end test, (@weight_pos:=(@weight_pos - weight)) curr_weight, @weight_point, #@keyword, @weight_pos, @rand, @weight_sum keywords ) t t.curr_weight < 0 limit 1;
Comments
Post a Comment