根据给定的分布随机为记录分配值

时间:2011-03-15 11:24:57

标签: sql sql-server tsql testing

我有一个生成测试数据的t-sql过程,作为其中的一部分,需要根据预定义的分布将几列随机设置为一组值。我目前有一个使用标识列和余数运算符%的方法,但我想知道是否有更优雅的方法来设计这个问题的解决方案,这将允许我参数化分配列的值和分布。

例如,

我想指定Column A三个值中的一个{Horse, Donkey, Pony}column B两个值中的一个{Big, Small}。在这种情况下,我希望分布相等,{Horse:1/3, Donkey 1/3, Pony, 1/3}, {Big:1/2, Small:1/2}Column B's分布应该取决于Column A(即小马的1/2应该是大的)

Record | ColumnA | ColumnB | OtherData
1 | Horse | Big |...
2 | Horse | Small |...
3 | Donkey | Big |...
4 | Donkey | Small |...
5 | Pony | Big |...
6 | Pony | Small |...

我希望对记录号码进行A和B列的半随机分配,但这不是必需的。

如果分配不完全可能,则应为所有剩余记录分配一个可能的值。假设在大型数据集中,这将自行完成。

1 个答案:

答案 0 :(得分:0)

不确定这对您的情况是否有帮助,但这适用于SQL Server 2005+。这是一组300条记录,每只动物100只,每只动物各50只。

在其他SQL语言中可能有类似的方法来解决这个问题。

DECLARE @MaxCount INT
SET @MaxCount = 300

SET NOCOUNT ON;
DECLARE @Numbers TABLE (Number INT NOT NULL IDENTITY);
INSERT @Numbers DEFAULT VALUES;
WHILE SCOPE_IDENTITY() < @MaxCount INSERT @Numbers DEFAULT VALUES;

SELECT  *
FROM    (
    SELECT  RandomSize.Number
    ,   RandomSize.Animal
    ,   CASE RandomSize.RowNumber % 2
            WHEN 0 THEN 'Big'
            WHEN 1 THEN 'Small'
        END Size
    FROM    (
        SELECT  DerivedAnimal.Number
        ,   DerivedAnimal.Animal
        ,   ROW_NUMBER() OVER (PARTITION BY DerivedAnimal.Animal ORDER BY NEWID()) RowNumber
        FROM    (
            SELECT  RandomAnimals.Number
            ,   CASE RandomAnimals.RowNumber % 3
                    WHEN 0 THEN 'Horse'
                    WHEN 1 THEN 'Donkey'
                    WHEN 2 THEN 'Pony'
                END Animal
            FROM    (
                SELECT  Number
                ,   ROW_NUMBER() OVER (ORDER BY NEWID()) RowNumber
                FROM    @Numbers
                ) RandomAnimals
            ) DerivedAnimal
        ) RandomSize
    ) FinalList
ORDER BY FinalList.Number