通过加权机会从DB中提取项目

时间:2009-07-19 19:23:14

标签: sql database temp-tables

假设我有一张充满记录的表格,我想从中提取随机记录。但是,我希望该表中的某些行比其他行更常出现(哪些行因用户而异)。使用SQL的最佳方法是什么?

我能想到的唯一方法是创建一个临时表,用我想要更常见的行填充它,然后用表中其他随机选择的行填充它。还有更好的方法吗?

3 个答案:

答案 0 :(得分:4)

我能想到的一种方法是在表格中创建另一列,即权重的滚动总和,然后通过生成0到所有权重总和之间的随机数来拉取记录,然后拉出行最高滚动和值小于随机数。

例如,如果您有四行具有以下权重:

+---+--------+------------+
|row| weight | rollingsum |
+---+--------+------------+
| a |      3 |          3 |
| b |      3 |          6 |
| c |      4 |         10 |
| d |      1 |         11 |  
+---+--------+------------+

然后,选择0到11之间的随机数n,如果a0<=n<3 b,则返回行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

答案 1 :(得分:0)

我不知道单独使用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()

这将考虑选择一组随机行以及应该重复多少行。然后,在您的应用程序逻辑中,您可以执行行复制并对结果进行随机播放。

答案 2 :(得分:0)

从3个表用户,数据和用户数据开始。用户数据包含每个用户应该首选的行。

然后根据用户首选的数据行创建一个视图。

创建第二个包含无首选数据的视图。

创建第三个视图,它是第一个视图的联合。联合应该从首选数据中选择更多行。

然后最后从第三个视图中选择随机行。