SQL Server - 将数据集划分为具有随机行的相同大小的组

时间:2017-01-16 13:58:58

标签: sql sql-server sql-server-2014

拥有一组基础数据集,即一组ID,F.E。

000
111
222
333
444
555
666
777
888
999

和密钥数据集

1 - 20
2 - 40
3 - 40

结果应该是根据定义的百分比随机配对基础数据集和密钥数据集,意味着20%将收到1,40%将收到2,40%将收到3

F.E。 - 第一次运行

000 - 1
111 - 2
222 - 3
333 - 1
444 - 2
555 - 3
666 - 2
777 - 3
888 - 2
999 - 3

第二次运行

000 - 2
111 - 3
222 - 2
333 - 3
444 - 2
555 - 3
666 - 1
777 - 3
888 - 2
999 - 1

使用SQL Server 2014

考虑到涉及循环和cusrors以及临时表的解决方案,但我想知道是否有“更清洁”且最有效的解决方案......

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用row_number()join执行此操作。我们的想法是累积关键的“值”(无论第二列是什么),然后将它们在0和1之间标准化。对于随机行排序和(基本上)使用between进行表格之间的映射:

with k as (
      select k.*,
             sum(val) over (order by id) * 1.0 / sum(sum(val)) over () as cume_sumval
      from keys k
     )
select d.*, k.id
from (select d.*,
             row_number() over (order by newid()) - 1 as seqnum,
             count(*) as cnt
      from dataset d
     ) d join
     k
     on seqnum >= (k.cume_sumval - v) * cnt and
        seqnum < (k.cume_sumval) * cnt;

答案 1 :(得分:1)

这是使用Numbers表的一种方法。

;WITH base_dataset
     AS (SELECT *,
                Row_number()OVER(ORDER BY id) AS rn
         FROM   (VALUES (000),
                        (111),
                        (222),
                        (333),
                        (444),
                        (555),
                        (666),
                        (777),
                        (888),
                        (999)) tc (ID)),
     keys
     AS (SELECT *
         FROM   (VALUES (1,20),
                        (2,50),
                        (3,30)) tc(val, per)),
     num_gen
     AS (SELECT 1        AS num,
                Count(1) AS cnt
         FROM   base_dataset
         UNION ALL
         SELECT num + 1,
                cnt
         FROM   num_gen
         WHERE  num < cnt)
SELECT Id,val
FROM   (SELECT Row_number()OVER(ORDER BY newid()) rn,
               val
        FROM   num_gen n
               JOIN keys k
                 ON n.num <= (k.per/100.0) * cnt) a
       JOIN base_dataset d
         ON d.rn = a.rn 

我已使用Recursive CTE生成数字,您可以在数据库中创建数字表并使用它