table1 有个字段weight记录0~5的整数,我要从表中虽机select出8条记录,要求weight值越高的,被select出来的机率越高

解决方案 »

  1.   

    NND.逼近函数没有找到。
    试试这个:select * from table1 order by floor(1+rand()*5) limit 8;
      

  2.   

    我对“几率”的概念有点疑惑,请教一下。我可不可以对weight降序排序,取前8条,即先取weight为5的,再取weight为4的........而几率的概念就是数据库里有5条weight为5的,随机选取,我取出4条,或者3条就叫被选出来的几率高?楼主要的是这样的吗?如果真是这样的,这个需求有点意思~~~~~
      

  3.   

    写法很多,因为你没有明确weight和几率的关系,比如: select * from table order by weight-rand()*5 limit 8 
    就可以, 
    weight=5,  weight-rand()*5 =>  0~5
    weight=4,  weight-rand()*5 => -1~4
    weight=3,  weight-rand()*5 => -2~3
    weight=2,  weight-rand()*5 => -3~2
    weight=1,  weight-rand()*5 => -4~1
    weight=0,  weight-rand()*5 => -5~0
    自然weight=5的容易排到前面
      

  4.   

    select * from table1 order by rand()*weight desc limit 8;思路: order by rand() 实际上是在所有的字段后附加一个字段 "rand()",一个随机的值,然后再按这个 "rand()" 字段正向排序。而 order by rand() desc 则是按  "rand()" 字段的反向排的(尽管得到的效果和前者一样),即 "rand()" 值越大排的越前。按LZ的要求, weight 越大,rand()*weight 产生的值会越大,加了 desc 后,越容易排到前面。
      

  5.   

    To helloyou0 :
    额... 你那个应该是weight=5的容易排到后面吧
      

  6.   

    helloyou0的方法倒一下就可以了。select * from lk11 order by weight - rand()*5 desc limit 8;
      

  7.   


    create table lk11(
    id int not null auto_increment primary key,
    weight int
    );
    insert into lk11(weight) values 
    (1),(2),(5),(3),(2),(3),(4),(4),(5),(3),(1),(3),(2),(4),(5);create index `k_w` on lk11(weight);
      

  8.   

    order by weight - rand()*5 desc 好像不是正比关系吧rand()*weight desc 中 weight 和几率成正比线性关系。
      

  9.   

    rand()*weight desc 和 weight 也不是成正比关系。rang()*5 不一定几率大的就是5
      

  10.   

    mysql>select * from table order by floor(weight-1+rand()*2) desc limit 8;
      

  11.   

    我试了了大家的方法,但是都是weight=5 4 3的机率很高,一直没select出weight=2 1,能把weight=2 1的机率略提高点吗
      

  12.   

    上面的公式都不对,概率是可能性,而不是weight=5就一定排在weight=0的前面select * from table order by (weight * rand() + rand())
    weight = 5, 0~6
    weight = 4, 0~5
    weight = 3, 0~4
    weight = 2, 0~3
    wegith = 1, 0~2
    weight = 0, 0~1
      

  13.   

    各位大哥的方法我都试了我limit 8,select出来的结果weight=5 4 3的机率很高,但一直没有select出weight=2 1,还有好的算法马?
      

  14.   

    select * from table1 order by rand()*SQRT(weight) desc limit 8;可减少差距
      

  15.   

    上面的要加desc, 谢谢指出~:)如果你对几率和weight的关系有要求,那么就要更明确一下这个关系~~~
    有个比较简单的方法, 你可以列一个表~~
    比如:
    如果你需要
    weight值    出现概率           出现条件
    5            30%=0.3       rand()<0.3
    4            25%=0.25      rand()<0.55
    3            20%=0.2       rand()<0.75
    2            15%=0.15      rand()<0.9
    1            10%=0.1       rand()<1可以这么写:
    SELECT * from tablename
    where 
    rand()< 
    CASE weight
       WHEN 5 THEN 0.3
       WHEN 4 THEN 0.55
       WHEN 3 THEN 0.75
       WHEN 2 THEN 0.9
       WHEN 1 THEN 1
    END 这样出来的是按照上面比例几率出现, 但是一般不止8条, 那么再平均随机从里面抽8条select * from 
    (
      SELECT * from tablename
      where 
      rand()< 
      CASE weight
       WHEN 5 THEN 0.3
       WHEN 4 THEN 0.55
       WHEN 3 THEN 0.75
       WHEN 2 THEN 0.9
       WHEN 1 THEN 1
      END
    ) x 
    order by rand() 
    limit 8这样能达到效果,但是这个语句无疑可以简化一下, 我先发了, 等我再看一下
      

  16.   

    上面的句子直接简化的结果是:SELECT *, rand() as ord 
    from tablename 
    where  
      rand() <  
      CASE weight 
       WHEN 5 THEN 0.3 
       WHEN 4 THEN 0.55 
       WHEN 3 THEN 0.75 
       WHEN 2 THEN 0.9 
       WHEN 1 THEN 1 
      END
    order by ord 
    limit 8和上面的同样效果但是,这个语句的效率是很差的, 
    两个rand()还要过滤和排序.....索引无法用.... 
    如果你数据不大, 要求不高, 思想不复杂, 人品不算好.....
    更重要的...老板给钱不多的话,先用...下次改进的时候再要钱
    我待会再继续聊
      

  17.   

    上面的其实还有点含义不清....说的出现概率并不是出现在最终结果的概率...还和数据中weight的分布有关..
    想想如果weight=1的有1000000000个, weight=5的有10个, 那么最终结果里出现5的概率肯定是非常非常小的...如果你说的几率是出现在最终结果的几率....和weight的多少无关的话....
    那么实际上....选8个....
    weight  概率   结果里大概
    5       0.3     8*0.3  ~=~ 2.4 个
    4       0.25    8*0.25 ~=~ 2   个
    3       0.2     8*0.2  ~=~ 1.6 个
    2       0.15    8*0.15 ~=~ 1.2 个
    1       0.1     8*0.1  ~=~ 0.8 个你就照这个比例随机取吧.......嘿嘿.......
    要逼真的话, 再用rand()让结果个数"晃动"一下,比如weight5的这次取3个,下次取2个,再下次取4个....最终平均下来接近2.4就行.....