选择之前未被选中的随机行?

时间:2012-04-05 22:30:15

标签: php mysql math

让我们把它放在最简单的一个有两个字段的表格中:'item_id'& 'times_seen'。

| item_id | times_seen |
----------+-------------
|   1001  |     48     |
|   1002  |     25     |
|   1003  |      1     |
|   1004  |     12     |
|   1005  |     96     |
|   1006  |     35     |

我正在尝试找到一种随机选择行的方法,但优先选择之前未被选中的项目。

(显然,在选择后会发送第二个查询以增加'times-seen'字段)

虽然我目前的“项目”是php / mysql,但如果可能的话,我会喜欢与语言无关的解决方案。我宁愿有一个基于数学的解决方案,可以在其他地方进行调整。我并不反对PHP解决方案。我只是想了解代码的工作原理,而不仅仅是复制和粘贴代码。

2 个答案:

答案 0 :(得分:2)

  1. 获取表格中的所有行
  2. 确定times_seen
  3. 的最大值
  4. 为每一行指定权重max - times_seen
  5. 根据权重从列表中选择
  6. 第4步是棘手的​​部分,但你可以这样做:

    $max = 1;
    $rows = array();
    
    $result = mysql_query("SELECT * FROM table");
    while ($row = mysql_fetch_array($result)){
        $max = max($max, $row['times_seen']);
        $rows[] = $row;
    }
    
    $pick_list = array();
    foreach ($rows as $row){
        $count = $max - $row['times_seen'];
        for ($i=0; $i<$count; $i++) $pick_list[] = $row['item_id'];
    }
    shuffle($pick_list);
    $item_id = array_pop($item_id);
    

    在SQL中完成所有操作:

    SELECT * 
    FROM table 
    ORDER BY RAND( ) * ( MAX( times_seen ) - times_seen ) DESC
    LIMIT 1
    

    这会选择一行,其权重与times_seen

    成反比

答案 1 :(得分:2)

SQL解决方案如何:

select * from item order by times_seen + Rand()*100 limit 1;

你随机乘以多少(它的值介于0和1之间)取决于你想要多少随机性。

修改:http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand