web-dev-qa-db-fra.com

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

Cette question demande à obtenir un échantillon aléatoire (ish) d'enregistrements sur SQL Server et la réponse était d'utiliser TABLESAMPLE. Existe-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 d'une requête qui renverra des millions normalement?

57
Jeremy French
SELECT  *
FROM    (
        SELECT  *
        FROM    mytable
        ORDER BY
                dbms_random.value
        )
WHERE rownum <= 1000
70
Quassnoi

La clause SAMPLE vous donnera un pourcentage d’échantillon 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 (semblable à 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
62
grokster

Ceci n’est pas une réponse parfaite mais donnera 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. Le plus souvent, j'ai simplement besoin d'un nombre arbitraire de lignes afin de ne pas limiter mes résultats. Sur ma base de données avec 2 millions de lignes, j’ai 2 secondes contre 60 secondes.

select * from mytable sample (0.01)
12
Arturo Hernandez
SELECT * FROM TABLE_NAME SAMPLE(1)

Vous donnera à Olny une part approximative de 1% plutôt que exactement 1/100 du nombre d'observations. La raison probable en est que Oracle génère un indicateur aléatoire pour chaque observation, indiquant si l'inclure 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 distribution réelle de la taille des échantillons sera binomiale.

6
Hors2force

La fonction exemple est utilisée pour les exemples de données dans Oracle. Donc, vous pouvez essayer comme ça: -

SELECT * FROM TABLE_NAME SAMPLE(50);

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

SELECT * FROM TABLE_NAME SAMPLE(1);

J'espère que cela peut vous aider.

3
Ankit Bajpai

Je sais que l'on a déjà répondu à cette question, mais, vu le nombre de visites ici, j'aimerais ajouter une version qui utilise la clause SAMPLE mais permet tout de même de filtrer les lignes en premier:

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.

3
Thomas Tschernich

On nous a donné pour mission de ne sélectionner que deux enregistrements dans la liste des agents..i.e 2 enregistrements aléatoires pour chaque agent sur une période d'une semaine, etc. ... et ci-dessous correspond à ce que nous avons obtenu et cela fonctionne.

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;
0
ChrisNZak

Quelque chose comme ça devrait marcher:

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 );
0
BASMA SHAWKY