Sélectionnez un échantillon aléatoire de résultats à partir d’un résultat de requête

Cette question concerne l’obtention d’un échantillon aléatoire (ish) d’enregistrements sur SQL Server et la réponse était d’utiliser TABLESAMPLE . Y a-t-il un équivalent dans Oracle 10?

S’il n’y en a pas, existe-t-il un moyen standard d’obtenir un échantillon aléatoire de résultats à partir d’un ensemble de requêtes? Par exemple, comment peut-on obtenir 1 000 lignes aléatoires à partir d’une requête qui renverra des millions normalement?

 SELECT * FROM ( SELECT * FROM mytable ORDER BY dbms_random.value ) WHERE rownum <= 1000 

La clause SAMPLE vous donnera un pourcentage aléatoire de toutes les lignes d’une table.

Par exemple, nous obtenons ici 25% des lignes:

 SELECT * FROM emp SAMPLE(25) 

Le code SQL suivant (utilisant l’une des fonctions analytiques) vous donnera un échantillon aléatoire d’un nombre spécifique de chaque occurrence d’une valeur particulière (similaire à un GROUP BY) dans une table.

Ici, nous échantillonnons 10 de chaque:

 SELECT * FROM ( SELECT job, sal, ROW_NUMBER() OVER ( PARTITION BY job ORDER BY job ) SampleCount FROM emp ) WHERE SampleCount <= 10 

Ce n’est pas une réponse parfaite, mais vous obtiendrez de bien meilleures performances.

 SELECT * FROM ( SELECT * FROM mytable sample (0.01) ORDER BY dbms_random.value ) WHERE rownum <= 1000 

Sample vous donnera un pourcentage de votre table réelle, si vous voulez vraiment 1000 lignes, vous devrez ajuster ce nombre. Plus souvent, j'ai juste besoin d'un nombre arbitraire de lignes, donc je ne limite pas mes résultats. Sur ma firebase database avec 2 millions de lignes, je reçois 2 secondes contre 60 secondes.

 select * from mytable sample (0.01) 

Il existe également une clause exemple spéciale pour sélectionner un pourcentage: http://oracleact.com/papers/sampleclause.html

 SELECT * FROM TABLE_NAME SAMPLE(1) 

Vous obtiendrez une part approximative de 1% plutôt que 1/100 du nombre d’observations. La raison probable est qu’Oracle génère un indicateur aléatoire pour chaque observation afin de déterminer si elle est incluse dans l’échantillon généré. L’argument 1 (1%) dans un tel processus de génération prend le rôle de probabilité que chaque observation soit sélectionnée dans l’échantillon.

Si cela est vrai, la dissortingbution réelle des tailles d’échantillon sera binomiale.

Je sais que cela a déjà été répondu, mais en voyant autant de visites ici, je voudrais append une version qui utilise la clause SAMPLE mais qui permet tout d’abord de filtrer les lignes:

 with cte1 as ( select * from t_your_table where your_column = 'ABC' ) select * from cte1 sample (5) 

Notez cependant que la sélection de base nécessite une colonne ROWID , ce qui signifie que cela peut ne pas fonctionner pour certaines vues par exemple.

La fonction d’échantillon est utilisée pour les données d’échantillon dans ORACLE. Vous pouvez donc essayer comme ceci: –

 SELECT * FROM TABLE_NAME SAMPLE(50); 

Ici, 50 est le pourcentage de données contenues dans la table. Donc, si vous voulez 1000 lignes de 100000. Vous pouvez exécuter une requête comme: –

 SELECT * FROM TABLE_NAME SAMPLE(1); 

J’espère que cela peut vous aider.

Quelque chose comme ça devrait fonctionner:

 SELECT * FROM table_name WHERE primary_key IN (SELECT primary_key FROM ( SELECT primary_key, SYS.DBMS_RANDOM.RANDOM FROM table_name ORDER BY 2 ) WHERE rownum <= 10 ); 

On nous a donné et assigné à sélectionner seulement deux enregistrements de la liste d’agents .. deux enregistrements aléatoires pour chaque agent pendant une semaine, etc.

 with summary as ( Select Dbms_Random.Random As Ran_Number, colmn1, colm2, colm3 Row_Number() Over(Partition By col2 Order By Dbms_Random.Random) As Rank From table1, table2 Where Table1.Id = Table2.Id Order By Dbms_Random.Random Asc) Select tab1.col2, tab1.col4, tab1.col5, From Summary s Where s.Rank <= 2;