Select SQL 中的随机数,具有相同值的多个实例
Select Random in SQL with multiple instances of the same value
考虑以下因素:
user_id weight
1 2
2 5
是否有一个查询可以随机 select 一个用户 ID,同时使用权重影响选择哪个 ID 的几率?
换句话说,在这种情况下,是否有一个查询会查看此 table 然后从以下组中随机选择 1 个用户 ID:
[UserID_001, UserID_001, UserID_002, UserID_002, UserID_002, UserID_002, UserID_002]
因此 UserID_002 有 5/7 的机会被 selected,而 UserId_001 有 2/7 的机会被 selected。
这就像每个用户在抽奖中都有多张彩票,User_001 有 2 张彩票,User_002 有 5 张彩票。是否可以用 SQL 查询来做这样的事情?或者我需要使用其他方法吗?
提前致谢!
您想要加权抽样。这实际上很容易,一旦你有了所有权重的累加和。
select t.*
from (select t.*,
(@w := @w + weight) as cumew
from table t cross join
(select @w := 0) init
) t
where @w * rand() <= cumew
order by weight
limit 1;
注意在外部查询中,@w
是所有权重的总和。因此,它将此乘以一个随机数并找到大于或等于此值的第一个累积权重。
这是您的彩票解决方案:-)
如果您需要查看它是如何工作的,只需注释查询的最后一行 WHERE ...
http://sqlfiddle.com/#!9/54a44/17
SELECT *
FROM (SELECT *,
IF(@total IS NULL,@first:=1, @first:=@total+1) from_number,
IF(@total IS NULL,@total:=tickets, @total:=@total+tickets) to_number,
IF(@winner IS NULL,@winner:= FLOOR( 1 + RAND( ) * t_sum.t_all), @winner) win
FROM tickets
LEFT JOIN (SELECT SUM(tickets) t_all FROM tickets) t_sum
ON 1) t
WHERE win >= from_number AND win <= to_number
考虑以下因素:
user_id weight
1 2
2 5
是否有一个查询可以随机 select 一个用户 ID,同时使用权重影响选择哪个 ID 的几率?
换句话说,在这种情况下,是否有一个查询会查看此 table 然后从以下组中随机选择 1 个用户 ID:
[UserID_001, UserID_001, UserID_002, UserID_002, UserID_002, UserID_002, UserID_002]
因此 UserID_002 有 5/7 的机会被 selected,而 UserId_001 有 2/7 的机会被 selected。
这就像每个用户在抽奖中都有多张彩票,User_001 有 2 张彩票,User_002 有 5 张彩票。是否可以用 SQL 查询来做这样的事情?或者我需要使用其他方法吗?
提前致谢!
您想要加权抽样。这实际上很容易,一旦你有了所有权重的累加和。
select t.*
from (select t.*,
(@w := @w + weight) as cumew
from table t cross join
(select @w := 0) init
) t
where @w * rand() <= cumew
order by weight
limit 1;
注意在外部查询中,@w
是所有权重的总和。因此,它将此乘以一个随机数并找到大于或等于此值的第一个累积权重。
这是您的彩票解决方案:-)
如果您需要查看它是如何工作的,只需注释查询的最后一行 WHERE ...
http://sqlfiddle.com/#!9/54a44/17
SELECT *
FROM (SELECT *,
IF(@total IS NULL,@first:=1, @first:=@total+1) from_number,
IF(@total IS NULL,@total:=tickets, @total:=@total+tickets) to_number,
IF(@winner IS NULL,@winner:= FLOOR( 1 + RAND( ) * t_sum.t_all), @winner) win
FROM tickets
LEFT JOIN (SELECT SUM(tickets) t_all FROM tickets) t_sum
ON 1) t
WHERE win >= from_number AND win <= to_number