使用随机值作为连接条件

时间:2010-02-05 12:03:45

标签: sql oracle join random

我正在生成一些测试数据并使用dbms_random。我在dbms_random的条件下使用JOIN时遇到了一些奇怪的行为,我无法解释:

------------------------# 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) )返回(1,2,3)中的随机数,因此我原本期望x的所有行都与x2的随机行连接,或者可能始终是如果随机数仅被评估一次,则x2的相同随机行。

多次尝试时,我得到的结果如下:

(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

我错过了什么?

修改

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

会在这种情况下得到结果,但为什么原始查询的行为类似?

1 个答案:

答案 0 :(得分:1)

要生成具有一个可预测值和一个随机值的三行,请尝试以下操作:

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

修改

为什么原始查询会返回一组不一致的行?

好吧,如果没有ON子句中的随机位,你的查询基本上是X对X的CROSS JOIN - 它会返回9行(至少如果语法允许的话,它会有)。这九行中的每一行都执行对DBMS_RANDOM.VALUE()的调用。仅当随机值与X2.ID的当前值匹配时,才是结果集中包含的行。因此,查询可以随机返回0-9行。

你的解决方案显然更简单 - 我没有足够的重构:)