2011-12-22 49 views
1

我有SQL表,我有列和概率。我想随机选择一行,但我想给更多机会更多的机会。我可以给予SQL列的范围

Order By abs(checksum(newid())) 

做到这一点,但概率之间的差异都太大,因此提供了更多的机会,最高probability.Like采摘看重它拿起另一个值一旦超过一次围绕74 times.I 74次后想要减少这一点。就像我想要3-4次,而不是其他所有。我想给范围的Probabilies.Its像

Row[i] = Row[i-1]+Row[i] 

我怎样才能做到这一点。做我需要创建功能?是否有任何有任何其他方式来实现this.I是neewby.Any帮助将感谢你

编辑: 我有我的问题的解决方案。我有一个问题 。 如果我有如下表格。

Column1 Column2 
    1   50 
    2   30 
    3   20 

我可以得到吗?

Column1 Column2 Column3 
    1   50  50 
    2   30  80 
    3   20  100 

每次我想增加现有的价值。是否有任何方法?

UPDATE: 终于得到解决3小时后,我只是把我的probailities的平方根这样我可以缩小体重它们。它就像我与

sqrt(sqrt(sqrt(Probability)))....:-) 
+0

为了澄清,你希望column3是所有其他(以前)条目和第2列中(当前)值的总和?这不是一个坏主意。但你想知道如何生成它?有几种方法,但我不确定什么是最好的。我会遇到的最大问题是插入所有值后该表是否是静态的。 – JayC 2011-12-22 20:23:35

+0

啊,我看到DNNX也有同样的理解。 – JayC 2011-12-22 20:33:17

回答

0

我添加列的区别倒是被什么东西处理它像

ORDER BY rand()*pow(<probability-field-name>,<n>) 

对于不同的n值,你会扭曲线性概率为简单的多项式。 n的较小值(例如0.5)将把概率压缩到1,因此使得较不可能的选择更可能,n的较大值(例如2)将做相反的处理,并进一步降低已经可能出现的值的概率。

+0

据我所知,这个pow是POWER函数。我试过了。每次我得到不同的行,但它对我所有的点击都是一样的。我也想改变选定的行。 – Hiren 2011-12-22 17:46:01

0

由于概率差异太大,您需要添加一个计算字段,其修订权重具有更均匀的概率分布。你如何做到这一点取决于你的数据和首选分布。一种方法是将权重“归一化”到1到10之间的整数,以便最低的概率永远不会比最高的十倍小。

0

回答你最近的问题:

SELECT t.Column1, 
     t.Column2, 
     (SELECT SUM(Column2) 
     FROM table t2 
     WHERE t2.Column1 <= t.Column1) Column3 
FROM table t 
+0

表t2在哪里? – Hiren 2011-12-22 18:40:09

+0

't'和't2'是table'table'的别名。他们引用相同的原始表格。 – DNNX 2011-12-22 18:41:12

+0

噢好吧我知道了。谢谢,我会尝试。 – Hiren 2011-12-22 18:43:12

0

这是一个基本的例子如何从表中选择一个行与考虑到所分配的行权重。

假设我们有表:

CREATE TABLE TableWithWeights(
    Id int NOT NULL PRIMARY KEY, 
    DataColumn nvarchar(50) NOT NULL, 
    Weight decimal(18, 6) NOT NULL -- Weight column 
) 

让我们填写表格有样本数据。

INSERT INTO TableWithWeights VALUES(1, 'Frequent', 50) 
INSERT INTO TableWithWeights VALUES(2, 'Common', 30) 
INSERT INTO TableWithWeights VALUES(3, 'Rare', 20) 

这是查询返回一个随机行并考虑给定的行权重。

SELECT * FROM 
    (SELECT tww1.*,  -- Select original table data 
    -- Add column with the sum of all weights of previous rows 
    (SELECT SUM(tww2.Weight)- tww1.Weight 
     FROM TableWithWeights tww2 
     WHERE tww2.id <= tww1.id) as SumOfWeightsOfPreviousRows 
    FROM TableWithWeights tww1) as tww, 
    -- Add column with random number within the range [0, SumOfWeights) 
    (SELECT RAND()* sum(weight) as rnd  
    FROM TableWithWeights) r 
WHERE 
     (tww.SumOfWeightsOfPreviousRows <= r.rnd) 
    and (r.rnd < tww.SumOfWeightsOfPreviousRows + tww.Weight) 

要检查查询结果,我们可以运行它100次。

DECLARE @count as int; 
SET @count = 0; 
WHILE (@count < 100) 
BEGIN 
    -- This is the query that returns one random row with 
    -- taking into account given row weights 
    SELECT * FROM 
     (SELECT tww1.*,  -- Select original table data 
     -- Add column with the sum of all weights of previous rows 
     (SELECT SUM(tww2.Weight)- tww1.Weight 
      FROM TableWithWeights tww2 
      WHERE tww2.id <= tww1.id) as SumOfWeightsOfPreviousRows 
     FROM TableWithWeights tww1) as tww, 
     -- Add column with random number within the range [0, SumOfWeights) 
     (SELECT RAND()* sum(weight) as rnd  
     FROM TableWithWeights) r 
    WHERE 
     (tww.SumOfWeightsOfPreviousRows <= r.rnd) 
    and (r.rnd < tww.SumOfWeightsOfPreviousRows + tww.Weight) 

    -- Increase counter 
    SET @count += 1 
END 

PS查询已在SQL Server 2008 R2上测试过。当然,查询可以优化(如果你有这个想法,很容易做到)