2

我有一个itemproperties表,我想从中获取一个随机itemproperty,但是我希望它的随机性比其他 itemproperties 更倾向于某些itemproperties

为了实现这一点,我设置了一个名为 rarity 的列用于存储该项目应该显示的频率(更高 = 更频繁),以及一个名为rarity_position的列,它是使用以下查询配置的:

SET @i:=0;UPDATE itemproperty SET rarity_position = @i:=@i+rarity;

这提供了以下结果:

稀有结果

然后抓取一个随机值,我想我会使用:

SELECT * FROM itemproperty 
WHERE id = (
        SELECT id 
        FROM itemproperty 
        WHERE rarity_position >= FLOOR
                (
                    RAND()*
                    (
                        SELECT MAX(rarity_position) FROM itemproperty
                    )
                )
        ORDER BY rarity_position 
        ASC LIMIT 1
) LIMIT 1

为了选择具有最高 rarity_position 最大值的随机数,然后获取 rarity_position 刚好高于该值的 item 属性。

大多数情况下,这按预期工作,但大约三分之一的时间没有结果。

可能相关的服务器信息:

Software: MySQL
Software version: 5.0.95-log - MySQL Community Server (GPL)
Protocol version: 10
Server charset: UTF-8 Unicode (utf8)

您可以使用此模型重现该行为:

create table itemproperty (
  id int, rarity int, rarity_position int
);
insert into itemproperty
values
  ( 1, 50, 50 ),
  ( 2, 50, 100 ),
  ( 3, 50, 150 ),
  ( 4, 50, 200 ),
  ( 5, 50, 250 ),
  ( 6, 50, 270 ),
  ( 7, 50, 320 ),
  ( 8, 50, 370 ),
  ( 9, 50, 420 ),
  ( 10, 50, 470 ),
  ( 11, 50, 520 )
;

如果您尝试仅执行子查询,则每次都有效:

    SELECT id 
    FROM itemproperty 
    WHERE rarity_position >= FLOOR
            (
                RAND()*
                (
                    SELECT MAX(rarity_position) FROM itemproperty
                )
            )
    ORDER BY rarity_position 
    ASC LIMIT 1

但是,如果您将其封装在:

SELECT * FROM itemproperty
WHERE id = (
 // here the above request
) LIMIT 1;

它不会按预期工作。

是什么导致它每次都没有返回结果?

4

2 回答 2

2
SELECT *
FROM itemproperty 
ORDER BY RAND() * rarity DESC
LIMIT 1
于 2012-11-29T22:16:21.013 回答
0

找到了一个类似于 zerkms 方法的可行解决方案:

ORDER BY -LOG(1.0 – RAND()) / rarity

来源

值得注意的是,缺少的部分似乎与以下问题有关: MySQL query with RAND() subquery condition

我猜在 WHERE 中有 RAND() 会导致一些奇怪。

于 2012-12-02T04:06:45.333 回答