2010-02-05 8 views
4

Je génère des données de test et utilise dbms_random. Je rencontrais un comportement étrange lors de l'utilisation dbms_random dans l'état de la JOIN, que je ne peux pas expliquer:Utilisation de la valeur aléatoire comme condition de jointure

------------------------# test-data (ids 1 .. 3) 
With x As (
    Select Rownum id From dual 
    Connect By Rownum <= 3 
) 
------------------------# end of test-data 
Select x.id, 
     x2.id id2 
    From x 
    Join x x2 On (x2.id = Floor(dbms_random.value(1, 4))) 


Floor(dbms_random.value(1, 4)) retourne un nombre aléatoire sur (1,2,3), donc je me serais attendu toutes les lignes de x à joindre avec une ligne aléatoire de x2, ou peut-être toujours la même ligne aléatoire de x2 dans le cas où le nombre aléatoire est évalué une seule fois.

Lorsque vous essayez plusieurs fois, j'obtenir des résultats comme ça, si:

(1) ID ID2  (2) ID ID2  (3) 
    ---- ----   ---- ----   no rows selected. 
     1 2    1 3 
     1 3    2 3 
     2 2    3 3 
     2 3 
     3 2 
     3 3 

Qu'est-ce que je manque?

EDIT:

SELECT ROWNUM, FLOOR(dbms_random.VALUE (1, 4)) 
FROM dual CONNECT BY ROWNUM <= 3 

obtiendrait le résultat dans ce cas, mais pourquoi la requête initiale se comporter comme ça?

Répondre

1

Pour générer trois lignes avec une valeur prévisible et une valeur aléatoire, essayez ceci:

SQL> with x as (
    2 select rownum id from dual 
    3 connect by rownum <= 3 
    4  ) 
    5  , y as (
    6 select floor(dbms_random.value(1, 4)) floor_val 
    7 from dual 
    8  ) 
    9 select x.id, 
10   y.floor_val 
11 from x 
12 cross join y 
13/

     ID FLOOR_VAL 
---------- ---------- 
     1   2 
     2   3 
     3   2 

SQL 

modifier

Pourquoi votre requête REMETTRE un ensemble incohérent de lignes? Eh bien, sans le bit aléatoire dans la clause ON, votre requête était essentiellement un CROSS JOIN de X contre X - il aurait retourné neuf lignes (du moins, cela aurait été le cas si la syntaxe l'avait permis). Chacune de ces neuf lignes exécute un appel à DBMS_RANDOM.VALUE(). Uniquement lorsque la valeur aléatoire correspond à la valeur actuelle de X2.ID est la ligne incluse dans le jeu de résultats. Par conséquent, la requête peut renvoyer 0-9 lignes, de manière aléatoire.

Votre solution est évidemment plus simple - je ne l'ai pas assez Refactor :)

+0

Merci, cela pourrait se faire encore plus facile, voir ma question mise à jour. Je me demandais pourquoi les résultats de ma requête sont si étranges, cependant ... Une idée? –