2015-05-14 23 views
5

Ho un database universitario e vorrei estrarre un campione casuale di dati di circa 1000 record.Esempio casuale SQL con gruppi

voglio garantire il campione è rappresentativo della popolazione in modo da includere le stesse proporzioni di corsi ad esempio

enter image description here

ho potuto fare questo usando il seguente:

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

ma abbiamo centinaia di codici di corsi, quindi questo richiederebbe molto tempo e mi piacerebbe poter riutilizzare questo codice per diverse dimensioni del campione e non voglio particolarmente passare attraverso la query e il codice rigido delle dimensioni del campione .

Qualsiasi aiuto sarebbe molto apprezzato

+1

Come fare per assicurarmi di ottenere le proporzioni corrette nel campione? –

+0

Come si calcola la dimensione del campione? Si basa sulla percentuale di popolazione? –

+0

Il campione verrebbe utilizzato per un questionario, quindi la dimensione del campione dipende da quanto budget abbiamo ... non molto scientifico lo so! –

risposta

9

Volete un campione stratificato. Consiglierei di farlo ordinando i dati per codice del corso e facendo un ennesimo esempio. Ecco un metodo che funziona meglio se si dispone di una grande dimensione della popolazione:

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:

È inoltre possibile calcolare la dimensione della popolazione per ogni gruppo "al volo":

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

Brillante, grazie. Ho appena eseguito un rapido controllo con i miei dati e la differenza più grande tra il campione e le proporzioni della popolazione era dello 0,748%, il che è perfettamente accettabile. –

1

Aggiungere una tabella per memorizzare population.

penso che dovrebbe essere simile a questo:

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

ho fatto ricerche simili (ma non su MS SQL) utilizzando un approccio 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

non è necessario per partizionare la popolazione.

Se si sta prelevando un campione di 1000 da una popolazione tra centinaia di codici di rotta, è ovvio che molti di quei codici di corso non saranno affatto selezionati in alcun campionamento.

Se la popolazione è uniforme (ad esempio, una sequenza continua di ID studente), un campione uniformemente distribuito sarà automaticamente rappresentativo della ponderazione della popolazione per codice di rotta. Dal momento che newid() è un campionatore casuale uniforme, sei pronto per iniziare.

L'unica ruga che si potrebbe incontrare è se un ID studente è associato a più codici di corso. In questo caso, crea un elenco univoco (tabella temporanea o sottoquery) contenente un ID sequenziale, l'id dello studente e il codice del corso, prova l'id sequenziale da esso, raggruppando per ID studente per rimuovere i duplicati.