mysql - SQL to get even distribution from n groups - fetch random items -
i have following tables:
table product id int(11) title varchar(400) table tag id int(11) text varchar(100) table product_tag_map product_id int(11) tag_id int(11)
product_tag_map maps tags product. distribution of tags in system isn't normal, i.e., tags have more products others.
i'm trying write sql fetch 25 random products: 5 products per tag, 5 tags (so that's 5x5 = 25).
found answer here: how can distribution using id in(1,2,3,4)
but doesn't yield random products - fetches same products per tag.
here sql have:
set @last_tag = 0; set @count_tag = 0; select distinct id ( select product.*, @count_tag := if(@last_tag = product_tag_map.tag_id, @count_tag, 0) + 1 tag_row_number, @last_tag := product_tag_map.tag_id product left join product_tag_map on (product_tag_map.product_id=product.id) product_tag_map.tag_id in (245,255,259,281,296) ) subquery tag_row_number <= 5;
how make return random products per tag?
any appreciated! thanks.
there lot of tricks in query :
- add level of nesting use limit in subquery : mysql subquery limit
- add row_number functionality mysql : how select first/least/max row per group in sql
the final result lot of subquery:
select tag.name, t0.id mapid ( select * , @num := if(@type = tag_id, @num + 1, 1) row_number , @type := tag_id dummy ( select * map m tag_id in ( select * ( select id tag order rand() limit 5 ) t ) order tag_id, rand() ) maintable , (select @num:=0) foo , (select @type:=0) foo2 ) t0 inner join tag on t0.tag_id = tag.id row_number <= 5
the idea select first 5 random tags. not difficult, simple order rand() limit 5
.
then tricky part simulate row_number() over(partition tag_id, rand())
, because ranking each item randomly, partition tag need. declare variable , query show.
finally, filter row_number, , have 25 random items!