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