小编典典

在SQL中有偏向随机性吗?

sql

我的数据库中有一些条目,例如我的视频,其中包含评分,受欢迎程度和其他因素。在所有这些因素中,我计算一个或多个可能性因素,或者说是一个提升因素。

所以本质上我有ID和BOOST字段。boost的计算方式是一个整数,表示该条目在比较中应该被击中的频率的百分比。

ID  Boost
1   1
2   2
3   7

因此,如果我无限期地运行随机函数,我应该在ID 1上获得X次点击,在ID 2上获得2倍,在ID 3上获得7倍。

因此,每次点击都应是随机的,但概率为(boost / sum of boosts)。因此,在此示例中ID
3的概率应为0.7(因为总和为10。为简单起见,我选择了这些值)。

我想到了类似以下查询的内容:

SELECT id FROM table WHERE CEIL(RAND() * MAX(boost)) >= boost ORDER BY rand();

不幸的是,在考虑了表中的以下条目后,这行不通了:

ID  Boost
1   1
2   2

机会只有50/50的情况下,只有第二个元素或两个元素可供选择。

因此,将0.5命中分配给第二个元素,将0.5命中分配给(第二个和第一个)元素,这些元素是随机选择的,因此每个0.25。所以我们最终得到0.25 /
0.75的比率,但是应该是0.33 / 0.66

我需要一些修改或新的方法来以良好的性能执行此操作。

我也考虑过要累积存储boost字段,所以我只需要从(0-sum())进行范围查询,但是如果我更改了它或开发了一些交换算法或其他东西,那么我将不得不重新索引一个项目之后的所有内容。真的不是优雅的东西。

插入/更新和选择都应该很快!

您对此问题有解决方案吗?

要考虑的最佳用例可能是广告投放。“请以给定的概率选择一个随机广告” …但是我需要将其用于其他目的,而只是给您最后一张图片它应该做什么。

编辑:

感谢kens的回答,我想到了以下方法:

  1. 从0和求出一个随机值(明显的提升)

SET @randval =(从测试中选择ceil(rand()* sum(DISTINCT boost)));

  1. 从所有明显超过随机值的不同提升因子中选择提升因子

那么我们在第一个示例1中的概率为0.1,2的概率为0.2,7的概率为0.7。

  1. 现在从所有具有该提升因子的条目中选择一个随机条目

问题:
因为一次提升的条目数总是不同的。例如,如果只有1个增强的项,那么我会在10个调用中有1个得到它,但是如果有1个具有7个调用,则几乎不会返回它们……因此这行不通:(尝试对其进行优化。

我必须以某种方式包括具有该提升因子的条目数…但是我却以某种方式停留在那…


阅读 130

收藏
2021-04-07

共1个答案

小编典典

您需要为每行生成一个随机数并对其加权。

在这种情况下,RAND(CHECKSUM(NEWID()))绕过的“每个查询”评估RAND。然后只需将其乘以boost,然后将ORDER
BY乘以结果DESC。该SUM..OVER给你的总升压

DECLARE @sample TABLE (id int, boost int)

INSERT @sample VALUES (1, 1), (2, 2), (3, 7)

SELECT
    RAND(CHECKSUM(NEWID())) * boost  AS weighted,
    SUM(boost) OVER () AS boostcount,
    id
FROM
    @sample
GROUP BY
    id, boost
ORDER BY
    weighted DESC

如果您有不同的提升值(我想您已经提到过),我也将考虑使用LOG(以e为底)来平滑分布。

最后,ORDER BY NEWID()是不考虑提升的随机性。播种RAND很有用,但不能单独播种。

该示例放到了SQL Server 2008 BTW上

2021-04-07