如何在sql中生成一个固定值的随机数范围

时间:2014-01-24 11:10:54

标签: sql oracle10g

我正在运行以下代码。对于每次执行,我都会得到查询结果。但是对于每次执行它都给了我不同的随机值SUPPLIER_ID。我想每次都修复SUPPLIER_ID的值。请帮帮我。

SELECT
    T.*,
    C.*,
    LC.SUPPLIER_NAME,
    L.LOCAL_COMMODITY_DESC,
    CASE WHEN C.INVOICE_DESCRIPTION IS NULL
    THEN 'NO'
    ELSE 'YES' END AS DEPEND_OTHER
FROM OYSTER_WEB3.TRANSACTION T,
Local_Feed_Commodity_Map L,
OYSTER3.CAT_RULE_MV C,
OYSTER3.LOCAL_COMMON_SUPPLIER_MAP LC
    WHERE
    C.CAT_RULE_ID=T.CAT_RULE_ID
    AND
    C.DATA_FEED_CODE=LC.DATA_FEED_CODE
    AND
    T.SUPPLIER_CODE=C.LOCAL_SUPPLIER_CODE
    AND
    C.LOCAL_SUPPLIER_CODE=LC.SUPPLIER_CODE
    AND
    T.DATA_FEED_CODE=L.DATA_FEED_CODE
    AND
    C.LOCAL_COMMODITY_CODE=L.LOCAL_COMMODITY_CODE
    AND
    L.Local_Commodity_Code =         (SUBSTR(T.LOCAL_COMMODITY_CODE,1,INSTR(T.LOCAL_COMMODITY_CODE,'~')-1))
    AND T.TRANSACTION_DATE>='01-JAN-09'
    AND LC.SUPPLIER_ID IN
    (select trunc(dbms_random.VALUE(21852,2268730)) num from dual CONNECT BY LEVEL<=200);

2 个答案:

答案 0 :(得分:4)

另一种方法是使用rownum生成伪随机数。您需要将当前查询放在CTE(使用with)或子查询中,并使用rownum子句生成seqnum作为列名称(例如order by)(所以它总是产生相同的结果):

select rownum as seqnum . . .
order by <whatever>

然后在外部查询中,您可以使用seqnum来选择行。例如,如果你想要大约10%,你可以做类似的事情:

 mod(seqnum*101-87, 101) = 17;

我只使用包含素数的表达式。如果你愿意,你可以做一个更复杂的表达。

这实际上提供了一个n-out-of-n样本。出于许多目的,这样的样本与随机样本一样好或甚至更好。

答案 1 :(得分:2)

不太确定在理解为什么你想要一个固定范围的随机数,但如果你这样做,你需要播种它。通常两次调用会得到不同的结果:

select trunc(dbms_random.VALUE(21852,2268730)) num from dual CONNECT BY LEVEL<=5;

       NUM
----------
   1691967 
   1536691 
    221687 
   1925527 
    793133 

select trunc(dbms_random.VALUE(21852,2268730)) num from dual CONNECT BY LEVEL<=5;

       NUM
----------
   1316523 
   1121136 
   1011501 
    242015 
   2182176 

如果您在每次通话前reset the seed value,您将获得相同的结果:

exec dbms_random.seed(42);
select trunc(dbms_random.VALUE(21852,2268730)) num from dual CONNECT BY LEVEL<=5;

       NUM
----------
    195911 
   1291100 
   1478849 
   1426372 
    784607 

exec dbms_random.seed(42);
select trunc(dbms_random.VALUE(21852,2268730)) num from dual CONNECT BY LEVEL<=5;

       NUM
----------
    195911 
   1291100 
   1478849 
   1426372 
    784607 

operational notes解释说:

  

DBMS_RANDOM可以显式初始化,但不需要   在调用随机数生成器之前初始化。它会   如果没有,则自动使用date,userid和process id初始化   执行显式初始化。

     

如果此包用同一种子播种两次,则访问   同样,它会在两种情况下产生相同的结果。

     

在某些情况下,例如测试时,您可能需要序列   随机数在每次运行时都是相同的。在那种情况下,你种下了   通过调用其中一个重载来生成具有常量值的生成器   DBMS_RANDOM.SEED。为每次运行生成不同的输出,只需   省略对“种子”的调用,系统将选择合适的种子   你。