2015-05-14 5 views
5

У меня есть база данных университетских выпускников и вы хотите получить случайную выборку данных из около 1000 записей.SQL случайный образец с группами

Я хочу, чтобы обеспечить образец является репрезентативной для населения, так хотелось бы включить те же пропорции курсов, например

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() 

но у нас есть сотни кодов курсов, поэтому это потребует много времени, и я хотел бы иметь возможность повторно использовать этот код для разных размеров выборки и особо не хочу проходить через запрос и жесткий код с размерами выборки ,

Любая помощь будет принята с благодарностью

+1

Как бы убедиться, что я получаю правильные пропорции в образце? –

+0

Как вы оцениваете размер выборки? Это зависит от процентной доли населения? –

+0

Образец будет использоваться для вопросника, поэтому размер выборки зависит от того, сколько у нас бюджета ... не очень я знаю! –

ответ

9

Вы хотите стратифицированной выборки. Я бы рекомендовал сделать это, сортируя данные по коду курса и выполняя 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; 

EDIT:

Вы также можете рассчитать численность населения для каждой группы «на лету»:

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) 
+0

Блестящий, спасибо. Я только что проверил свои данные, и самая большая разница между выборкой и численностью населения составила 0,748%, что вполне приемлемо. –

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 
0

Я делал подобные запросы (но не на MS SQL), используя row_number подход:

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 
1

это не необходимо разделить население вообще.

Если вы принимаете образец 1000 из популяции среди сотен курсовых кодов, то разумно, что многие из этих кодов курса вообще не будут выбраны ни в одной выборке.

Если совокупность является однородной (скажем, непрерывной последовательностью идентификаторов учеников), равномерно распределенный образец автоматически будет представлять собой взвешивание населения по курсу. Поскольку newid() является равномерным случайным сэмплером, вы можете выйти из коробки.

Единственная морщина, с которой вы можете столкнуться, - это если идентификатор студента связан с несколькими кодами курсов. В этом случае создайте уникальный список (временная таблица или подзапрос), содержащий последовательный идентификатор, идентификатор студента и код курса, примерный идентификатор последовательности из него, группировка по идентификатору студента для удаления дубликатов.

Смежные вопросы