【问题标题】:Giving Range to the SQL Column为 SQL 列提供范围
【发布时间】:2023-03-30 19:55:02
【问题描述】:

我有 SQL 表,其中有 column 和 Probability 。我想从中随机选择一行,但我想给更多的机会来获得更多的概率。我可以做到这一点

    Order By abs(checksum(newid()))

但是概率之间的差异太大了,所以它给最高概率提供了更多的机会。就像在选择 74 次该值之后,它再次选择另一个值大约 74 次。我想减少这个。就像我想要 3 -4 倍于它,比其他和所有。我正在考虑将 Range 赋予 Probabilies.Its Like

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

我该怎么做。我需要创建函数吗?有没有其他方法可以实现这一点。我是 neewby。任何帮助都会得到帮助。谢谢

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

    Column1   Column2
     1         50
     2         30
     3         20

我可以得到吗?

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

每次我想用现有的增加价值。有什么办法吗?

更新: 3小时后终于得到了解决方案,我只是取我的概率的平方根,这样我就可以缩小它们的差异。就像我添加列一样

    sqrt(sqrt(sqrt(Probability)))....:-)

【问题讨论】:

  • 澄清一下,您希望 column3 是所有其他(以前的)条目和第 2 列中的(当前)值的总和?这不是一个坏主意。但是您想知道如何生成它?有几种方法,但我不确定哪种方法最好。我最大的问题是插入所有值后表格是否是静态的。
  • 啊,我看到DNNX的回答也是一样的。

标签: sql select random-sample weighted


【解决方案1】:

我会用类似的方式来处理它

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

对于不同的 n 值,您会将线性概率扭曲为一个简单的多项式。较小的 n 值(例如 0.5)会将概率压缩为 1,从而使不太可能的选择更有可能,较大的 n 值(例如 2)将起到相反的作用,并进一步降低已经不可能的值的概率。

【讨论】:

  • 据我所知,这个 pow 是 POWER 功能。我已经尝试过了。每次我得到不同的行,但对于我的所有点击来说都是一样的。我也想更改选定的行。
【解决方案2】:

由于概率差异太大,您需要添加一个具有修正权重的计算域,该权重具有更均匀的概率分布。如何做到这一点取决于您的数据和首选分布。一种方法是将权重“标准化”为 1 到 10 之间的整数,这样最低概率不会比最高概率小十倍。

【讨论】:

    【解决方案3】:

    回答您最近的问题:

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

    【讨论】:

    • tt2 是表 table 的别名。它们引用了相同的原始表格。
    • 哦,好的,我知道了。谢谢,我要试试。
    【解决方案4】:

    这是一个基本示例,如何在考虑分配的行权重的情况下从表中选择一行。

    假设我们有一张桌子:

    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 上进行了测试。当然查询可以优化(如果你明白了,这很容易做到)

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 2011-03-24
      • 1970-01-01
      • 2021-10-05
      • 2015-11-24
      相关资源
      最近更新 更多