均匀分布随机

时间:2015-07-02 13:48:26

标签: sql sql-server

我想知道是否有人知道如何在Sql Server中生成均匀分布范围内的随机值。这就是我所做的:

SELECT ID, AlgorithmType, AlgorithmID
FROM TEvaluateAlgorithm

我想AlgorithmID取值从0到15,必须均匀分布

UPDATE TEA SET TEA.AlgorithmID = FLOOR(RAND(CONVERT(VARBINARY, NEWID()))*(16))
-- FROM TEvaluateAlgorithm TEA

我不知道随机发生了什么,但是没有在0到15之间分配均匀的随机值,而不是相同的量。 例如,0到9大于10到15。

提前致谢!

编辑:

这是我的数据,你可以看到差异......

AlgorithmID COUNT(*)

    0   22254
    1   22651
    2   22806
    3   22736
    4   22670
    5   22368
    6   22690
    7   22736
    8   22646
    9   22536
    10  14479
    11  14787
    12  14553
    13  14546
    14  14574
    15  14722

2 个答案:

答案 0 :(得分:2)

rand()没有做好这件事。因为你想要整数,我建议如下:

select abs(checksum(newid()) % 16

我刚刚使用:

检查了这个
select val, count(*)
from (select abs(checksum(newid()) % 16
      from master..spt_values
     ) t
group by val
order by val;

并且分发看起来合理。

答案 1 :(得分:0)

这是概念的快速证明。

@Loops设置为足以使统计信息有意义的内容。 50k似乎是一个不错的起点。

@MinValue设置为集合中的最小整数,并将@TotalValues设置为集合中所需的整数。如问题中所述,0和16可以获得16个值[0-15]

我们将使用随机函数将50k输出填充到临时表中,然后在其上运行一些统计数据......

DECLARE @MinValue int
DECLARE @TotalValues int

SET @MinValue = 0
SET @TotalValues = 16

DECLARE @LoopCounter bigint
SET @LoopCounter = 0

DECLARE @Loops bigint
SET @Loops = 50000

CREATE TABLE #RandomValues
(
    RandValue int
)

WHILE @LoopCounter < @Loops
    BEGIN

        INSERT INTO #RandomValues (RandValue) VALUES (FLOOR(RAND()*(@TotalValues-@MinValue)+@MinValue))
        --you can plug into the right side of the above equation any other randomize formula you want to test
        SET @LoopCounter = @LoopCounter + 1

    END


--raw data query
SELECT
    RandValue AS [Value],
    COUNT(RandValue) AS [Occurrences],
    ((CONVERT(real, COUNT(RandValue))) / CONVERT(real, @Loops)) * 100.0 AS [Percentage]
FROM
    #RandomValues
GROUP BY
    RandValue
ORDER BY
    RandValue ASC

--stats on your random query

SELECT
    MIN([Percentage]) AS [Min %],
    MAX([Percentage]) AS [Max %],
    STDEV([Percentage]) AS [Standard Deviation]
FROM
    (   
    SELECT
        RandValue AS [Value],
        COUNT(RandValue) AS [Occurrences],
        ((CONVERT(real, COUNT(RandValue))) / CONVERT(real, @Loops)) * 100.0 AS [Percentage]
    FROM
        #RandomValues
    GROUP BY
        RandValue
    --ORDER BY
    --  RandValue ASC
    ) DerivedRawData

DROP TABLE #RandomValues

请注意,您可以在INSERT循环中的WHILE语句的右侧插入任何其他随机化公式,然后重新运行以查看您是否更喜欢结果。 “均匀分布”有点主观,但标准差结果是可量化的,您可以确定它是否可接受。