假设我有一张表,里面装满了我想从中提取随机记录的记录。但是,我希望该表中的某些行比其他行更频繁地出现(并且哪些行因用户而异)。使用 SQL 解决这个问题的最佳方法是什么?
我能想到的唯一方法是创建一个临时表,用我想要更常见的行填充它,然后用表中其他随机选择的行填充它。有没有更好的办法?
假设我有一张表,里面装满了我想从中提取随机记录的记录。但是,我希望该表中的某些行比其他行更频繁地出现(并且哪些行因用户而异)。使用 SQL 解决这个问题的最佳方法是什么?
我能想到的唯一方法是创建一个临时表,用我想要更常见的行填充它,然后用表中其他随机选择的行填充它。有没有更好的办法?
我能想到的一种方法是在表中创建另一列,这是您的权重的滚动总和,然后通过生成介于 0 和所有权重总和之间的随机数来拉取记录,并拉取滚动最高的行总和值小于随机数。
例如,如果您有四行具有以下权重:
+---+--------+------------+
|row| weight | rollingsum |
+---+--------+------------+
| a | 3 | 3 |
| b | 3 | 6 |
| c | 4 | 10 |
| d | 1 | 11 |
+---+--------+------------+
然后,在 0 到 11 之间选择一个随机数n
,包括 0 和 11,并返回行a
if 0<=n<3
,b
if 3<=n<6
,依此类推。
以下是有关生成滚动总和的一些链接:
http://dev.mysql.com/tech-resources/articles/rolling_sums_in_mysql.html
http://dev.mysql.com/tech-resources/articles/rolling_sums_in_mysql_followup.html
从 3 个表用户、数据和用户数据开始。用户数据包含每个用户应该首选哪些行。
然后根据用户喜欢的数据行创建一个视图。
创建没有首选数据的第二个视图。
创建第三个视图,它是前两个的联合。联合应该从首选数据中选择更多行。
然后最后从第三个视图中选择随机行。
我不知道单独使用 SQL 可以很容易地完成它。使用 T-SQL 或类似方法,您可以编写一个循环来复制行,或者您可以使用 SQL 来生成执行行复制的指令。
我不知道你的概率模型,但你可以使用这样的方法来实现后者。鉴于这些表定义:
RowSource
---------
RowID
UserRowProbability
------------------
UserId
RowId
FrequencyMultiplier
您可以编写这样的查询(特定于 SQL Server):
SELECT TOP 100 rs.RowId, urp.FrequencyMultiplier
FROM RowSource rs
LEFT JOIN UserRowProbability urp ON rs.RowId = urp.RowId
ORDER BY ISNULL(urp.FrequencyMultiplier, 1) DESC, NEWID()
这将负责选择一组随机的行以及应该重复多少行。然后,在您的应用程序逻辑中,您可以进行行复制并对结果进行洗牌。