Re: Force randomize within a set of numbers
Date: Fri, 4 Dec 2009 07:12:50 -0800 (PST)
Message-ID: <78ea86f1-80bf-44fd-96f2-10091453a854_at_o9g2000prg.googlegroups.com>
On Dec 3, 5:01 pm, CrazyKarma <ska..._at_gmail.com> wrote:
> Here is the last one for this week..I guess :)
>
> Is there way to force the randomize within a set of number in Oracle?
> Say I have a set of integers ( 2,8,6,5)
> and I want to force randomize function to randomly pick within that
> set only.
>
> I know about the DBMS_RANDOM package, sample and seed clause but none
> help what I need to do here.
>
> any thoughts?
>
> CK
Here is another way to do it, if you do not know how many elements will be in the list.
First, we return a row from DUAL with the rows of interest with a
comma appended at the start and end:
SELECT
',2,8,6,5,54,100,67,7778,6,' ITEMS
FROM
DUAL;
ITEMS
,2,8,6,5,54,100,67,7778,6,
Next, we need to determine the number of elements and pick an element
position at random:
SELECT
ITEMS,
SUM(SIGN(INSTR(ITEMS, ',',1,ROWNUM)))-1 NUM_ITEMS,
(TRUNC(DBMS_RANDOM.VALUE(0,SUM(SIGN(INSTR(ITEMS ,',',1,ROWNUM)))-1))
+1) SEL_ITEM
FROM
(SELECT
',2,8,6,5,54,100,67,7778,6,' ITEMS
FROM
DUAL)
CONNECT BY
LEVEL<20;
ITEMS NUM_ITEMS SEL_ITEM -------------------------- ---------- ---------- ,2,8,6,5,54,100,67,7778,6, 9 6
Finally, we push the above SQL statement into an inline view, search
for the specified number of commas according to SEL_ITEM column to
determine the starting position of the element, and then search for
the next comma to determine the ending position of the element:
SELECT
ITEMS,
SEL_ITEM,
SUBSTR(ITEMS,INSTR(ITEMS,',',1,SEL_ITEM)+1,(INSTR(ITEMS,',',
1,SEL_ITEM+1)) - (INSTR(ITEMS,',',1,SEL_ITEM)) -1) ITEM
FROM
(SELECT
ITEMS,
SUM(SIGN(INSTR(ITEMS, ',',1,ROWNUM)))-1 NUM_ITEMS,
(TRUNC(DBMS_RANDOM.VALUE(0,SUM(SIGN(INSTR(ITEMS ,',',1,ROWNUM)))-1))
+1) SEL_ITEM
FROM
(SELECT
',2,8,6,5,54,100,67,7778,6,' ITEMS
FROM
DUAL)
CONNECT BY
LEVEL<20);
ITEMS SEL_ITEM ITEM -------------------------- ---------- ---- ,2,8,6,5,54,100,67,7778,6, 6 100
-- You might also be able to do something like this: SELECT '2,8,6,5,54,100,67,7778,6' ITEMS, DBMS_RANDOM.VALUE(0,1) PERCENT FROM DUAL; ITEMS PERCENT ------------------------ ---------- 2,8,6,5,54,100,67,7778,6 .582165524 SELECT ROWNUM ITEM_NUMBER, REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) ITEM, PERCENT FROM (SELECT '2,8,6,5,54,100,67,7778,6' ITEMS, DBMS_RANDOM.VALUE(0,1) PERCENT FROM DUAL) CONNECT BY REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) IS NOT NULL; ITEM_NUMBER ITEM PERCENT ----------- ----- ---------- 1 2 .104480002 2 8 .81670697 3 6 .826051929 4 5 .477132421 5 54 .89077554 6 100 .640842927 7 67 .145088893 8 7778 .252241096 9 6 .490905924 As you can see from the above, we have a problem in that the random percent changes for each row, which will cause a problem for us if we try to use it in a WHERE clause. SELECT MAX(ITEM_NUMBER) OVER () NUM_ITEMS, PERCENT_RANK() OVER (ORDER BY ITEM_NUMBER) PR, ITEM_NUMBER, ITEM, PERCENT FROM (SELECT ROWNUM ITEM_NUMBER, REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) ITEM, PERCENT FROM (SELECT '2,8,6,5,54,100,67,7778,6' ITEMS, DBMS_RANDOM.VALUE(0,1) PERCENT FROM DUAL) CONNECT BY REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) IS NOT NULL); NUM_ITEMS PR ITEM_NUMBER ITEM PERCENT --------- ---------- ----------- ----- ---------- 9 0 1 2 .110718377 9 .125 2 8 .306241972 9 .25 3 6 .953005936 9 .375 4 5 .033518415 9 .5 5 54 .803485415 9 .625 6 100 .456278133 9 .75 7 67 .04461405 9 .875 8 7778 .249680394 9 1 9 6 .484834331 If we now use a FIRST_VALUE analytic function, we could just retrieve the first PERCENT value and use that in a WHERE clause: SELECT NUM_ITEMS, ITEM_NUMBER, ITEM FROM (SELECT MAX(ITEM_NUMBER) OVER () NUM_ITEMS, ITEM_NUMBER, ITEM, FIRST_VALUE(PERCENT) OVER () PERCENT FROM (SELECT ROWNUM ITEM_NUMBER, REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) ITEM, PERCENT FROM (SELECT '2,8,6,5,54,100,67,7778,6' ITEMS, DBMS_RANDOM.VALUE(0,1) PERCENT FROM DUAL) CONNECT BY REGEXP_SUBSTR(ITEMS,'\w+',1,LEVEL) IS NOT NULL)) WHERE ITEM_NUMBER=(TRUNC(NUM_ITEMS*PERCENT)+1); NUM_ITEMS ITEM_NUMBER ITEM --------- ----------- ---- 9 7 67 Charles Hooper Co-author of "Expert Oracle Practices: Oracle Database Administration from the Oak Table" http://hoopercharles.wordpress.com/ IT Manager/Oracle DBA K&M Machine-Fabricating, Inc.Received on Fri Dec 04 2009 - 09:12:50 CST