DBMS_RANDOM Function
I would like to return a number between 0-9999 through the dbms_random function. I am trying this:
exec dbms_random.initialize(1234);
select dbms_random.random from dual;
RANDOM
-3.10E+08
this is not what I am looking for. Anyone know how I can get the desired results I am looking for?
SQL> SELECT DBMS_RANDOM.Value(0,9999) FROM dual;
DBMS_RANDOM.VALUE(0,9999)
2499.13527
SQL> /
DBMS_RANDOM.VALUE(0,9999)
6274.76354TTFN
John
Similar Messages
-
Use of DBMS_AQ.LISTEN
Hello, I have created a queue in which someone else constantly enqueues messages (about 20000 every 15 minutes) and I have added and registered some subscriber to dequeue the messages, with the packages dbms_aq.add_subscriber and dbms_aq.register.
Although it works fine, I don't like this solution because, if I stop and restart the queue (for administration reasons), the messages arrived when the queue is stopped aren't dequeued by any subscriber.
So I think to use DBMS_AQ.LISTEN, but I'm not sure which is the best way to use it. These are my issues: do I have to use DBMS_JOB to schedule it ? or better, which is the best way to launch and use the LISTEN procedure ?
Maybe this is not the best practice to use AQ, so every suggestion will be very appreciated.
Thanks,
EnnioHi Philippe,
no, I didn't find detailed information about this issue, nobody answered to my question about links or documentation, so actually I don't konw which are the best practises to use the LISTEN or the AQ.
But maybe I can help you. Some days ago I was playing with the AQ and I wanted to implement something like your issue.
Before explaining what I did, you need to know that:
- I suppose I need 10 subscribers
- the queue owner is ENNIO
- the name of the queue is EVENT_QUEUE
- the paylod of the queue is EVENT_TYPE
- the name of the subscribers are EVENT_CONSUMER_[1..10]
Then I suppose you know how to create the queue (remember to set the multiple_consumer parameter to TRUE) and that you know how to write the notify callback which dequeues the message.
First of all, I haven't any priority need: every message have the some priority than the others. For this reason, I use the priority option to determine which subscriber have to dequeue the message in this way:
1) create the subscribers with a LOOP:
begin
FOR priority IN 1..10
LOOP
dbms_aqadm.add_subscriber (
queue_name => 'ENNIO.EVENT_QUEUE',
subscriber => sys.aq$_agent( 'EVENT_CONSUMER_' || priority, null, null )
, rule => 'TAB.PRIORITY = ' || priority
END LOOP;
end;
Look at the RULE parameter: this is the first key of the solution.
2) register the subscribers with a LOOP:
DECLARE
reginfolist sys.aq$_reg_info_list;
BEGIN
reginfolist := sys.aq$_reg_info_list(
sys.aq$_reg_info('ENNIO.EVENT_QUEUE:EVENT_CONSUMER_1',
DBMS_AQ.NAMESPACE_AQ,
'plsql://ENNIO.notifyCB',
HEXTORAW('FF')
FOR priority IN 2..10
LOOP
reginfolist.EXTEND;
reginfolist(priority) :=
sys.aq$_reg_info('ENNIO.EVENT_QUEUE:EVENT_CONSUMER_' || priority,
DBMS_AQ.NAMESPACE_AQ,
'plsql://ENNIO.notifyCB',
HEXTORAW('FF')
END LOOP;
dbms_aq.register ( reginfolist, 10 );
END;
Now what you need is to enqueue the messages so that, in a RANDOM way, every message can be read just by one consumer. To do this I use the RANDOM PLSQL function and this is my enqueue procedure:
PROCEDURE enqueue (
hostname in VARCHAR2,
event in VARCHAR2,
data in DATE
AS
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle RAW(16);
message ENNIO.event_type;
BEGIN
message_properties.priority := DBMS_RANDOM.value(1,10);
message := event_type(hostname, event, data);
dbms_aq.enqueue(queue_name => 'ENNIO.EVENT_QUEUE',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
COMMIT;
DBMS_OUTPUT.put_line('EVENTO ACCODATO: PRIORITY=' || message_properties.priority);
END enqueue;
The DBMS_RANDOM function is the second key of the solution: in this way, every message has a random priority value, which is used to determine which will be the consumer that will dequeue the message.
As I told you I don't know well the AQ, the Oracle Agents and the procedure/functions to use in these contexts, so I don't know if there are better ways to do it.
Finally, I'm not sure the LISTEN function is really necessary, but I haven't found usefull documentation about it.
Finally (again:)), are you sure the subscriber is a good way ? I mean: if you stop the dequeue, but leaving the enqueue active, after you restart the queue, the subscribers will not read the messages arrived in the meanwhile.
I hope my example could help you and maybe that someone else could help us to understand more in depth the AQ world.
Bye,
Ennio -
Hi
I have a table,
id name
1 a:b:c
2 x:y
I want to see below
1 a
1 b
1 c
2 x
2 y
How can I do
thank for your helpIt's really sad that someone with a fancy "Guru" tag employs such condescension and contempt for others asking serious questions.
I'm well acquainted with the Oracle documentation & "Fine Manuals". I'm also a regular user of Google. I've used the "Connect By" and I'm well acquainted with the DBMS_random function. However, I've not been able to find anywhere, yet, a good explanation of how they are interacting in this example.
If you can't offer genuine help to someone asking a serious question, why not go do something useful instead of trolling this forum looking for people to make fun of. -
Why a function column created inside a view is executed more than once when called more than once?
EXAMPLE:
create or replace view aux1 as
date_column,
any_function(date_column) column1
from any_table
create or replace view aux2 as
column1 c1,
column1 c2,
column1 c3
from aux1
select * from aux2
It will execute 3 times the function any_function... logically the value will be the same for all columns...
I understand why!... are 3 calls... but...
Why not to create a "small" verification and if the function column was execute replace the second, the third... value? ... instead of execute 3, 4... times...
tks
BragaActually, this is more than a performance issue. This is a consistency problem. If the function is NOT deterministic then you may get different values for each call which is clearly not consistent with selecting 3 copies of the same column from a row. Oracle appears to have fixed this in 9i...
Connected to:
Oracle8i Enterprise Edition Release 8.1.7.2.0 - Production
With the Partitioning option
JServer Release 8.1.7.2.0 - Production
create view v1 as select dbms_random.value(1,100) r from dual;
create view v2 as select r r1, r r2 from v1;
select * from v2;
R1 R2
93 74
Connected to:
Oracle9i Enterprise Edition Release 9.0.1.3.0 - Production
With the Partitioning option
JServer Release 9.0.1.3.0 - Production
create view v1 as select dbms_random.value(1,100) r from dual;
create view v2 as select r r1, r r2 from v1;
select * from v2;
R1 R2
78 78Richard -
Error while inserting data using DBMS_RANDOM
Hi ,
I tried the following insert command in the link http://www.oracle-base.com/articles/misc/RollupCubeGroupingFunctionsAndGroupingSets.php
BANNER
Oracle Database 10g Release 10.2.0.1.0 - Production
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> INSERT INTO dimension_tab
2 SELECT TRUNC(DBMS_RANDOM.value(low => 1, high => 3)) AS fact_1_id,
3 TRUNC(DBMS_RANDOM.value(low => 1, high => 6)) AS fact_2_id,
4 TRUNC(DBMS_RANDOM.value(low => 1, high => 11)) AS fact_3_id,
5 TRUNC(DBMS_RANDOM.value(low => 1, high => 11)) AS fact_4_id,
6 ROUND(DBMS_RANDOM.value(low => 1, high => 100), 2) AS sales_value
7 FROM dual
8 CONNECT BY level <= 1000;
SELECT TRUNC(DBMS_RANDOM.value(low => 1, high => 3)) AS fact_1_id,
ERROR at line 2:
ORA-00907: missing right parenthesisCould you please advice me to get the correct recordssmile wrote:
Hi ,
I tried the following insert command in the link http://www.oracle-base.com/articles/misc/RollupCubeGroupingFunctionsAndGroupingSets.php
BANNER
Oracle Database 10g Release 10.2.0.1.0 - Production
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> INSERT INTO dimension_tab
2 SELECT TRUNC(DBMS_RANDOM.value(low => 1, high => 3)) AS fact_1_id,
3 TRUNC(DBMS_RANDOM.value(low => 1, high => 6)) AS fact_2_id,
4 TRUNC(DBMS_RANDOM.value(low => 1, high => 11)) AS fact_3_id,
5 TRUNC(DBMS_RANDOM.value(low => 1, high => 11)) AS fact_4_id,
6 ROUND(DBMS_RANDOM.value(low => 1, high => 100), 2) AS sales_value
7 FROM dual
8 CONNECT BY level <= 1000;
SELECT TRUNC(DBMS_RANDOM.value(low => 1, high => 3)) AS fact_1_id,
ERROR at line 2:
ORA-00907: missing right parenthesisCould you please advice me to get the correct recordsYou can't used named parameters for function/procedure calls in SQL until version 11.
You'll have to remove the
low => And stick with the good old "positional" way of doing things. -
Sample-function in select-statement
hello,
i have a sql statement to get 10% of the cutomers using the sample function:
select count(*) from
(select * from L_CUST sample(10));
The table C_CUST contains 1800001 rows.
if i execute the given statement, the resulut number of rows are different in range 1000
1800001 * 0.10 = 180000
if the number of rows differs between 0 and 2 record, its ok, but 1000 is to mutch.
hast anyone an idea?If you read the documentation you will see that Oracle selects a random sample. It's the random part that's obviously confusing you. A 10% sample does not select every 10th row. Rather it says for each row there's a 1 in 10 chance of that row being selected. It's just like flipping a coin, only with ten values rather than two.
If you are really bothered by this try...
SELECT * FROM
( SELECT rownum as rn, a.* FROM
( SELECT * FROM your_table
ORDER BY dbms_random.random ) a )
WHERE mod(rn, 10) = 0
/Cheers, APC
Cheers, APC -
Using oracle function in order by clause
Hello,
can i use report query or report that generate query like this :
select fname, lname from peoples order by dbms_random.value;
dbms_random is an oracle function to generate random value.
Thnaksadd the following call to your query:
query.addOrdering(query.getExpressionBuilder().getFunction("dbms_random.value"));
--Gordon -
How to use Rand() (ANSI Function)as such in Oracle
I need to use Rand() function as such in ANSI format in oracle how to use it.
I don't want to use the available DBMS_RANDOM.RANDOM(), i want to use ANSI Function as such in Oracle
Please help meI don't want to use the available DBMS_RANDOM.RANDOM()Whats wrong with dbms_andom?
In any case you can simply write a function wrapper to have same functionality as rand():
SQL> create or replace function rand (max_val int default 32767)
return int
as
begin
return dbms_random.value (0, max_val);
end rand;
Function created.
SQL> select rand(50) from dual
RAND(50)
44
1 row selected. -
hallo,
i would like to know how DBMS_RANDOM package can be implemented.
can you please explain with example.
is there any other means of performimg random sampling?
thank you
regards,
raoHi
Desc DBMS_RANDOM;
PROCEDURE INITIALIZE
Názov argumentu Typ In/Out predvolene?
VAL BINARY_INTEGER IN
FUNCTION NORMAL RETURNS NUMBER
FUNCTION RANDOM RETURNS BINARY_INTEGER
PROCEDURE SEED
Názov argumentu Typ In/Out predvolene?
VAL BINARY_INTEGER IN
PROCEDURE SEED
Názov argumentu Typ In/Out predvolene?
VAL VARCHAR2 IN
FUNCTION STRING RETURNS VARCHAR2
Názov argumentu Typ In/Out predvolene?
OPT CHAR IN
LEN NUMBER IN
PROCEDURE TERMINATE
FUNCTION VALUE RETURNS NUMBER
FUNCTION VALUE RETURNS NUMBER
Názov argumentu Typ In/Out predvolene?
LOW NUMBER IN
HIGH NUMBER IN
Example in SQL+:
Exec DBMS_RANDOM.INITIALIZE(100);
SELECT DBMS_RANDOM.Normal
, DBMS_RANDOM.RANDOM
, DBMS_RANDOM.VALUE()
, DBMS_RANDOM.VALUE(10,100)
FROM DUAL;
milos -
View + stored function + synonym for other user
Dear All!
I've got a quite strange problem which I cannot decide whether it's caused by my lack of knowledge on the appropriate topic or by an Oracle bug. I'm already after some heavy googling on the topic and I was unable to track any valuable answers neither in forums nor in the Oracle documentation. I'll try to be as short and specific as possible.
Database: Oracle 10g
Result of "SELECT BANNER FROM V$VERSION":
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
"CORE 10.2.0.4.0 Production"
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
I have two users in the database for a single Web application: UAPP01, which is the owner of application DB objects and UAPP02 which is the application user connecting to the DB. The application runs for quite many years by now and DB structure layout has always been following a simple logic: for each DB object used by the app. (tables, views, packages and stored procedures/functions) and found in the UAPP01 there exists a synonym in the UAPP02 schema. For the privileges to be set correctly a role is created: RL_MY_APPL which is granted the necessary privileges on objects of UAPP01 (CRUD on tables, SELECT on views, EXECUTE on procedures, etc..). This role is granted to UAPP02.
In the previous days I was about to extend the DB with a view that invokes a stored function. This pattern has already occured in the DB previously so I kept following existing conventions: I've created the stored function and the view in the UAPP01 schema, granted SELECT on the view to RL_MY_APPL and created the synonym for it in the UAPP02 schema. This is where the entire functionality began to act strange. I'll try to explain with a simplified example that was sufficient to reproduce the problem:
REM ========================================
REM Execute below code as UAPP01 user.
REM ========================================
REM Test function.
CREATE OR REPLACE FUNCTION testfunction(p_param NUMBER) RETURN NUMBER IS
BEGIN
RETURN p_param *2;
END;
REM Testview version 1. causing trouble.
CREATE OR REPLACE VIEW testview AS
WITH testdata AS
SELECT /*+ materialize*/ LEVEL AS d
FROM dual CONNECT BY LEVEL <= 100
SELECT a, b, c, SUM(d) AS sum_d
FROM
SELECT FLOOR(dbms_random.VALUE(1, 100)) a, FLOOR(dbms_random.VALUE(1, 100)) b, FLOOR(dbms_random.VALUE(1, 100)) c, testfunction(d) AS d
FROM testdata
GROUP BY CUBE(a, b, c)
REM Testview version 2. not causing trouble.
CREATE OR REPLACE VIEW testview AS
SELECT a, b, c, SUM(d) AS sum_d
FROM
SELECT FLOOR(dbms_random.VALUE(1, 100)) a, FLOOR(dbms_random.VALUE(1, 100)) b, FLOOR(dbms_random.VALUE(1, 100)) c, testfunction(d) AS d
FROM
SELECT LEVEL AS d FROM dual CONNECT BY LEVEL <= 100
GROUP BY (a, b, c)
REM Synonym.
CREATE OR REPLACE SYNONYM UAPP02.testview FOR UAPP01.testview;
REM Grants.
GRANT SELECT ON testview TO RL_MY_APPL;
When creating TESTVIEW with the 1 ^st^ version I cannot query it using the UAPP02 user, I'm constantly getting the error: ORA-00904: : invalid identifier. However, when I use the 2 ^nd^ version everything runs perfectly. What is common in the two cases is that both versions use the TESTFUNCTION function. I have not granted the EXECUTE rights on TESTFUNCTION to the RL_MY_APPL since it was never needed previously (for other views using stored functions) and as far as I know it's not necessary (as both the view and the function are owned by UAPP01). The strange thing in the above behaviour is that the function is used by both versions, however only one of them fails. This is where I thought it's not a granting issue, otherwise neither of the versions would have worked and I think I would have received a different error stating that UAPP02 lacks the necessary privileges on underlying objects of the view.
As I further digged into the problem by examining the EXPLAIN PLAN output for the two versions I found that version 1. leads to a TEMP TABLE TRANSFORMATION and to MULTI TABLE INSERTs, whereas version 2. simply executes the query without doing such things. In my setup I presume the MULTI TABLE INSERTs were caused by the GROUP BY CUBE. When I simply removed the CUBE and used only GROUP BY the TEMP TABLE TRANSFORMATION remained in place but the MULTI TABLE INSERTs disappeared. As a result of this small modification the view again began to work when I executed it through the synonym and using the UAPP02 user.
With the original DB objects of our application the behaviour is even more strange: the error comes up if I select from the view and filter for a column that is grouped in the query whereas it works correctly if I filter for the aggregated columns. However, I couldn't reproduce this with the above simplified example.
No problem occurs with any of the versions if I query the view using the UAPP01 user.
This hectic behaviour made me suspect that the TEMP TABLE TRANSFORMATION + MULTI TABLE INSERT + synonym + stored function combo appears to bring a strange Oracle bug to the surface...
As a final note: when executing GRANT EXECUTE ON TESTFUNCTION TO RL_MY_APPL everything works fine in all cases. I know I could simply live with this but I'd really like to get to the bottom of this. Although this extra GRANT appears to solve the problem I don't really trust it. I'd really like to avoid the bug emerging again in Production in case this extra GRANT were not sufficient due to some unknown misteries.
Excuse me, the post has become a bit lengthy. Thanks in advance for anyone who's willing to read through and answer it!
Regards,
Krisztian Balazs SzaniszloThe error is thrown at run-time and only for the UAPP02 (second) user.
The problem is that the appearance of errors is independent of whether the query contains the call to the stored function or not.
So far I thought that if I use a stored function indirectly, like in this setup: UAPP02.synonym -> UAPP01.view -> UAPP01.stored function, then I don't need the grant. Of course, I understand that if I had used it directly, like :UAPP02.synonym -> UAPP01.stored function then I'd need the GRANT EXECUTE.
Shall I just ignore the strange behaviour and go on by adding GRANT EXECUTE privilege on all the functions used indirectly through views? It seems to solve the problem, but this behaviour is disturbing me quite and I fear the real root cause of the problem can emerge later in a different fashion. -
My problem in RESULT CACHE FUNCTION
Hi
Please pay attention to my scenario
I use Oracle 11.2.0.3
create table chr1 (n1 number(8,3),n2 number(8,3),n3 number(8,3));
begin
for i in 1..1000 loop
insert into chr1 values (dbms_random.value(1,1000),dbms_random.value(1,1000),dbms_random.value(1,1000));
end loop;
end;
commit;
create or replace function chr1_f1(d1 natural) return number
result_cache relies_on(chr1)
is
n1 number:=0;
begin
for rec in (select n1,n2,n3 from chr1 order by n1) loop
n1:=n1+(rec.n1*rec.n2/rec.n3)/d1;
end loop;
return(n1);
end;
now I run this query
select chr1_f1(31) from dual;
CHR1_F1(31)
39732.3985
And I delete chr1 table
delete chr1;
1000 rows deleted.
commit;
commit complete;
Now I run the query again
select chr1_f1(31) from dual;
CHR1_F1(31)
39732.3985
It shows me the last result
Why the cached result doesn't become invalid when I delete the rows?
thanksSQL> create table chr1 (n1 number(8,3),n2 number(8,3),n3 number(8,3));
Table created
SQL>
SQL> begin
2 for i in 1..1000 loop
3 insert into chr1 values (dbms_random.value(1,1000),dbms_random.value(1,1000),dbms_random.value(1,1000));
4 end loop;
5 end;
6
7 /
PL/SQL procedure successfully completed
SQL> commit;
Commit complete
SQL>
SQL> create or replace function chr1_f1(d1 natural) return number
2 result_cache relies_on(chr1)
3 is
4 n1 number:=0;
5 begin
6 for rec in (select n1,n2,n3 from chr1 order by n1) loop
7 n1:=n1+(rec.n1*rec.n2/rec.n3)/d1;
8 end loop;
9 return(n1);
10 end;
11 /
Function created
SQL>
SQL> select chr1_f1(31) from dual;
CHR1_F1(31)
61602.84493
SQL> delete chr1;
1000 rows deleted
SQL> commit;
Commit complete
SQL> select chr1_f1(31) from dual;
CHR1_F1(31)
0
SQL>
Oracle result_cache tips
it is unclear how Oracle manages the invalidation mechanism with SQL and "alter session" syntax.
Ramin Hashimzade -
Hi All,
I have to use rand function in my procedure. Please anyone give me the alternate for that.
Thanks,
Ram.SQL> select dbms_random.random from dual;
RANDOM
399882104
SQL> select dbms_random.value(1,10) from dual;
DBMS_RANDOM.VALUE(1,10)
9.829218
SQL> -
COUNT(DISTINCT) WITH ORDER BY in an analytic function
-- I create a table with three fields: Name, Amount, and a Trans_Date.
CREATE TABLE TEST
NAME VARCHAR2(19) NULL,
AMOUNT VARCHAR2(8) NULL,
TRANS_DATE DATE NULL
-- I insert a few rows into my table:
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '20', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/02/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '21', TO_DATE('06/03/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '68', TO_DATE('06/04/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/05/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '20', TO_DATE('06/06/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '43', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '77', TO_DATE('06/02/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '221', TO_DATE('06/03/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '43', TO_DATE('06/04/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '73', TO_DATE('06/05/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
commit;
/* I want to retrieve all the distinct count of amount for every row in an analytic function with COUNT(DISTINCT AMOUNT) sorted by name and ordered by trans_date where I get only calculate for the last four trans_date for each row (i.e., for the row "Anna 110 6/5/2005 8:00:00.000 PM," I only want to look at the previous dates from 6/2/2005 to 6/5/2005 and get the distinct count of how many amounts there are different for Anna). Note, I cannot use the DISTINCT keyword in this query because it doesn't work with the ORDER BY */
select NAME, AMOUNT, TRANS_DATE, COUNT(/*DISTINCT*/ AMOUNT) over ( partition by NAME
order by TRANS_DATE range between numtodsinterval(3,'day') preceding and current row ) as COUNT_AMOUNT
from TEST t;
This is the results I get if I just count all the AMOUNT without using distinct:
NAME AMOUNT TRANS_DATE COUNT_AMOUNT
Anna 110 6/1/2005 8:00:00.000 PM 2
Anna 20 6/1/2005 8:00:00.000 PM 2
Anna 110 6/2/2005 8:00:00.000 PM 3
Anna 21 6/3/2005 8:00:00.000 PM 4
Anna 68 6/4/2005 8:00:00.000 PM 5
Anna 110 6/5/2005 8:00:00.000 PM 4
Anna 20 6/6/2005 8:00:00.000 PM 4
Bill 43 6/1/2005 8:00:00.000 PM 1
Bill 77 6/2/2005 8:00:00.000 PM 2
Bill 221 6/3/2005 8:00:00.000 PM 3
Bill 43 6/4/2005 8:00:00.000 PM 4
Bill 73 6/5/2005 8:00:00.000 PM 4
The COUNT_DISTINCT_AMOUNT is the desired output:
NAME AMOUNT TRANS_DATE COUNT_DISTINCT_AMOUNT
Anna 110 6/1/2005 8:00:00.000 PM 1
Anna 20 6/1/2005 8:00:00.000 PM 2
Anna 110 6/2/2005 8:00:00.000 PM 2
Anna 21 6/3/2005 8:00:00.000 PM 3
Anna 68 6/4/2005 8:00:00.000 PM 4
Anna 110 6/5/2005 8:00:00.000 PM 3
Anna 20 6/6/2005 8:00:00.000 PM 4
Bill 43 6/1/2005 8:00:00.000 PM 1
Bill 77 6/2/2005 8:00:00.000 PM 2
Bill 221 6/3/2005 8:00:00.000 PM 3
Bill 43 6/4/2005 8:00:00.000 PM 3
Bill 73 6/5/2005 8:00:00.000 PM 4
Thanks in advance.you can try to write your own udag.
here is a fake example, just to show how it "could" work. I am here using only 1,2,4,8,16,32 as potential values.
create or replace type CountDistinctType as object
bitor_number number,
static function ODCIAggregateInitialize(sctx IN OUT CountDistinctType)
return number,
member function ODCIAggregateIterate(self IN OUT CountDistinctType,
value IN number) return number,
member function ODCIAggregateTerminate(self IN CountDistinctType,
returnValue OUT number, flags IN number) return number,
member function ODCIAggregateMerge(self IN OUT CountDistinctType,
ctx2 IN CountDistinctType) return number
create or replace type body CountDistinctType is
static function ODCIAggregateInitialize(sctx IN OUT CountDistinctType)
return number is
begin
sctx := CountDistinctType('');
return ODCIConst.Success;
end;
member function ODCIAggregateIterate(self IN OUT CountDistinctType, value IN number)
return number is
begin
if (self.bitor_number is null) then
self.bitor_number := value;
else
self.bitor_number := self.bitor_number+value-bitand(self.bitor_number,value);
end if;
return ODCIConst.Success;
end;
member function ODCIAggregateTerminate(self IN CountDistinctType, returnValue OUT
number, flags IN number) return number is
begin
returnValue := 0;
for i in 0..log(2,self.bitor_number) loop
if (bitand(power(2,i),self.bitor_number)!=0) then
returnValue := returnValue+1;
end if;
end loop;
return ODCIConst.Success;
end;
member function ODCIAggregateMerge(self IN OUT CountDistinctType, ctx2 IN
CountDistinctType) return number is
begin
return ODCIConst.Success;
end;
end;
CREATE or REPLACE FUNCTION CountDistinct (n number) RETURN number
PARALLEL_ENABLE AGGREGATE USING CountDistinctType;
drop table t;
create table t as select rownum r, power(2,trunc(dbms_random.value(0,6))) p from all_objects;
SQL> select r,p,countdistinct(p) over (order by r) d from t where rownum<10 order by r;
R P D
1 4 1
2 1 2
3 8 3
4 32 4
5 1 4
6 16 5
7 16 5
8 4 5
9 4 5buy some good book if you want to start at writting your own "distinct" algorythm.
Message was edited by:
Laurent Schneider
a simpler but memory killer algorithm would use a plsql table in an udag and do the count(distinct) over that table to return the value -
Dbms_random distribution
What number distribution does the random number generator in the dbms_random package produce?
Michael Peddemors (guest) wrote:
: Is the DBMS_RANDOM package included in the 8.0.5 distribution?
: My calls to it are the typical..
: PLS-00201: identifier 'DBMS_RANDOM.INITIALIZE' must be declared
Okay, Thanks, found that $ORACLE_HOME/rdbms/admin/dbmsrand.sql
and ran it but.. it required the dbms_crypto_toolkit
So, I found dbmsoctk.sql but it has no function body
ORA-04068: existing state of packages has been discarded
ORA-04067: not executed, package body "SYS.DBMS_CRYPTO_TOOLKIT"
does not exist
ORA-06508: PL/SQL: could not find program unit being called
ORA-06512: at "SYS.DBMS_RANDOM", line 19
ORA-06512: at line 7
Did a grep of all the .sql files and found few bodies, EXCEPT in
the dbmsrand.sql...
But it requires this.. anyone??
null -
DBMS_RANDOM.Random
hi,
i want to see all the options available in DBMS_RANDOM package.
like the same how can i see from DBMS_LOB,AND other dbms packages.
is there any dictionary is available.
please advice.
thanks
sivasankar.sEverything you wanted to know about DBMS_XXXX packages...
http://download-east.oracle.com/docs/cd/B19306_01/appdev.102/b14258/toc.htm
.... excerpt below....
DBMS_RANDOM
Using DBMS_RANDOM
Security Model
Operational Notes
Summary of DBMS_RANDOM Subprograms
INITIALIZE Procedure
NORMAL Function
RANDOM Procedure
SEED Procedures
STRING Function
TERMINATE Procedure
VALUE Functions Message was edited by:
Mark Reichman
Maybe you are looking for
-
Mail wont open after servicing
I had the Macbook serviced at the Arden Fair. The genius "cleaned up" the laptop by pressing option and inserting the install disk at the same time. It took about 45 minutes. Now my Mail application will not open. Apple states that I must pay 49.9
-
Payment means shows wrong check number
Dear All, Once we have added an outgoing payment and go back to the payment means window, it shows the wrong check number and not the one initially entered. Please advice on why this is occuring and how to solve this problem. Kind Regards, Monil.
-
OBIEE 11g EVALUATE function working fine with Administrator but
Hi, We have a report with EVALUATE function , which is working fine with Administrator User but when we run for other users its giving following error. State: HY000. Code: 10058. [NQODBC] [SQL_STATE: HY000] [nQSError: 10058] A general error has occur
-
Photoshop CC is crashing regularly when I perform Save For Web function
I'm finding that my Photoshop CC, running on Windows, is continually crashing - most notably following a Shift+Ctrl+Alt+S command. Any ideas?
-
Detect first and last spark list items
Hi, I have a custom item renderer with a background image for each item in a list. the thing is I'm trying to have a different background for the first and last items (curved respectively) and I'm not sure how to do that. Any help will be appreciated