具有组

时间:2015-05-14 10:54:59

标签: sql sql-server sample random-sample

我有一个大学毕业生数据库,想要提取大约1000条记录的随机数据样本。

我想确保样本代表人口,所以希望包含相同比例的课程,例如

enter image description here

我可以使用以下方法执行此操作:

select top 500 id from degree where coursecode = 1 order by newid()
union
select top 300 id from degree where coursecode = 2 order by newid()
union
select top 200 id from degree where coursecode = 3 order by newid()

但是我们有数百个课程代码,所以这会耗费时间,我希望能够将这些代码重用于不同的样本大小,并且不要特别想要查看查询并对代码大小进行硬编码

非常感谢任何帮助

4 个答案:

答案 0 :(得分:13)

你想要一个分层的样本。我建议通过按课程代码对数据进行排序并执行第n个样本来完成此操作。如果您的人口规模很大,这里有一种最有效的方法:

select d.*
from (select d.*,
             row_number() over (order by coursecode, newid) as seqnum,
             count(*) over () as cnt
      from degree d
     ) d
where seqnum % (cnt / 500) = 1;

编辑:

您还可以“动态”计算每个群体的人口规模:

select d.*
from (select d.*,
             row_number() over (partition by coursecode order by newid) as seqnum,
             count(*) over () as cnt,
             count(*) over (partition by coursecode) as cc_cnt
      from degree d
     ) d
where seqnum < 500 * (cc_cnt * 1.0 / cnt)

答案 1 :(得分:1)

添加一个用于存储population的表。

我认为应该是这样的:

SELECT *
FROM (
    SELECT id, coursecode, ROW_NUMBER() OVER (PARTITION BY coursecode ORDER BY NEWID()) AS rn
    FROM degree) t
    LEFT OUTER JOIN
    population p ON t.coursecode = p.coursecode
WHERE
    rn <= p.SampleSize

答案 2 :(得分:1)

根本没有必要对人口进行分区。

如果您从数百个课程代码的人口中抽取1000个样本,那么很明显,在任何一个抽样中都不会选择许多课程代码。

如果人口统一(例如,连续的学生ID序列),均匀分布的样本将自动代表课程代码的人口加权。由于newid()是一个统一的随机抽样器,你可以开箱即用。

您可能遇到的唯一问题是学生证是否与多个课程代码相关联。在这种情况下,创建一个包含顺序ID,学生ID和课程代码的唯一列表(临时表或子查询),从中对其中的顺序ID进行采样,按学生ID分组以删除重复项。

答案 3 :(得分:0)

我使用ROW_NUMBER方法完成了类似的查询(但不是在MS SQL上):

select ...
from 
 ( select ...
     ,row_number() over (partition by coursecode order by newid()) as rn
   from degree
 ) as d 
join sample size as s
on d.coursecode = s.coursecode
and d.rn <= s.samplesize