Rank as aggregate function - help

Hi all

I am trying to learn oracle RANK as an aggregate function.

After that I run under request.

with temp (No., name, dept, sal) as

(select 1, 'aaa', 20, 32254 double Union all

Select 2, 'eee', 20, 45615 double Union all

Select 3, 'fff', 10, double union all 34645

Select 4, 'bbb', 30, double union all 45734

Select 9, 'mmm', 30, 23225 double Union all

Select 8, "nnn", 20, double union all 43565

Select 5, 'bbb', 20, double union all 56116

Select 7, "ccc", 30, double union all 45166

Select 6, 'ccc', 20, double 75166)

Select

Rank (45166) WITHIN GROUP (order by sal) as rank_1,

Rank (10,45166) WITHIN GROUP (stopped by the Department, sal) as rank_2,

Rank (45166,2) GROUP WITHIN (order by sal, no.) as rank_3

temp;

I get the output voltage:

rank_1 > 5

rank_2 > 2

rank_3 > 5

Here, how is the value of rank_2 is 2 and rank_3 is 5, I expect that two column should be zero because it does not correspond with the records.

Please help me understand, how does the row aggregate function is the species.

Thanks for all help you. Please let me know for further details.

If possible, any study link to learn the rank of aggregate function.

Oracle version:

Oracle Database 11 g Enterprise Edition Release 11.2.0.3.0 - 64 bit Production

PL/SQL Release 11.2.0.3.0 - Production

"CORE 11.2.0.3.0 Production."

AMT for Linux: Version 11.2.0.3.0 - Production

NLSRTL Version 11.2.0.3.0 - Production

Its says not where is the match - but where it appears in the list - game or not.

It's your list sorted by dept, sal

SAL DEPT

---------- ----------

10 34645

32254 20

20 43565

20 45615

20 56116

20 75166

30 23225

45166 30

30 45734

10,45166 would appear in the slot 2

Tags: Database

Similar Questions

  • Groovy aggregate function based on condition

    Hi all

    I use jdev 12.1.3.0.0

    I've set up an aggregate function in my master EO as explained in the blog

    https://blogs.Oracle.com/ADF/entry/using_groovy_aggregate_functions_in

    I need to add a condition to the number of records based on an attribute of the object of details view. Algorithm for the use case is

    detailsAccessor.count ("SmsId")

    where detailsAccessor.MessageType is equal to "file."

    Could you help me write an expression to achieve this functionality.

    Thank you

    Mozakkir

    All aggregate in groovy functions accept a groovy as a parameter expression.

    So instead of detailsAccessor.count("SmsId") you can try something like: detailsAccessor.count ("MessageType is 'Applicant'")

    Or convert sum() like this: detailsAccessor.sum ("MessageType is"Applying"? 1: 0 ")"

    Dario

  • Using java user-defined aggregate function

    Hello

    I'm trying to implement a with Java user-defined aggregate function.

    Here's the Code Javaclass:

    Import Java.util;
    Oracle.sql import. *;
    import java.sql. *;
    import Java.Math.BigDecimal;
    Oracle import. CartridgeServices.*;

    stored the context type

    public class StoredCtx_SecMax
    {
    private BigDecimal b_max;
    private BigDecimal b_secmax;

    public StoredCtx_SecMax()
    {
    b_max = new BigDecimal (0);
    b_secmax = new BigDecimal (0);
    }

    public void SchreibeMax (entry BigDecimal)
    {
    b_max = entry;
    }

    public void SchreibeSecMax (entry BigDecimal)
    {
    b_secmax = entry;
    }

    public BigDecimal LeseMax()
    {
    Return b_max;
    }

    public BigDecimal LeseSecMax()
    {
    Return b_secmax;
    }
    }

    implementation type

    / public class SecondMax_j implements SQLData
    {
    BigDecimal private key;

    Ultimate SUCCESS of static BigDecimal = new BigDecimal (0);
    Final static BigDecimal ERROR = new BigDecimal (1);


    Implement the SQLData interface.

    String sql_type;
    public String getSQLTypeName() throws SQLException
    {
    Return sql_type;
    }

    ' Public Sub readSQL (SQLInput stream, string typeName) throws SQLException
    {
    sql_type = typeName;
    key = stream.readBigDecimal ();
    }

    Public Sub writeSQL (SQLOutput stream) throws SQLException
    {
    stream.writeBigDecimal (key);
    }


    methods of the type that implements ODCITable interface

    public static BigDecimal ODCIAggregateInitialize (oracle.sql.STRUCT [] sctx)
    throws SQLException
    {
    Connection Conn = DriverManager.getConnection("jdbc:default:connection:");

    create a stored environment and store the result set in it
    StoredCtx_SecMax ctx = new StoredCtx_SecMax();

    context of registry stored with cartridge services
    Touch int;
    try {}
    key = ContextManager.setContext (ctx);
    } catch {} (EC CountException)
    error return;
    }

    Create an instance of StockPivotImpl and store the key of
    Object [] impAttr = new Object [1];
    impAttr [0] = new BigDecimal (key);
    StructDescriptor sd = new StructDescriptor ("SECONDMAX_J", conn);
    SCTX [0] = new STRUCT(sd,conn,impAttr);

    return a SUCCESS;
    }

    public BigDecimal ODCIAggregateIterate (BigDecimal input)
    throws SQLException
    {
    retrieve the context stored with the key
    CTX StoredCtx_SecMax;
    try {}
    CTX = (StoredCtx_SecMax) ContextManager.GetContext (Key.intValue ());
    } catch (InvalidKeyException ik) {}
    error return;
    }

    BigDecimal b_max;
    BigDecimal b_secmax;

    b_max = ctx. LeseMax();
    b_secmax = ctx. LeseSecMax();

    If (eingabe.compareTo (b_max) == 1)
    {
    CTX. SchreibeSecMax (b_max);
    CTX. SchreibeMax (input);
    }
    on the other
    {
    If (eingabe.compareTo (b_secmax) == 1)
    {
    CTX. SchreibeSecMax (input);
    }
    }

    return a SUCCESS;
    }

    public BigDecimal ODCIAggregateTerminate (double [] returnValue, int flags) throws SQLException {}

    retrieve the context stored with the key
    CTX StoredCtx_SecMax;
    try {}
    CTX = (StoredCtx_SecMax) ContextManager.clearContext (Key.intValue ());
    } catch (InvalidKeyException ik) {}
    error return;
    }

    returnValue [0] = ctx. LeseSecMax () .doubleValue ();

    CTX = null;

    return a SUCCESS;
    }


    public BigDecimal ODCIAggregateMerge (oracle.sql.STRUCT ctx2) throws SQLException {}


    return a SUCCESS;
    }
    }


    To implement this in the database, I use the following script:

    CREATE OR REPLACE TYPE IMPROG. SECONDMAX_J as object

    (
    INTEGER key,

    public static function ODCIAggregateInitialize (sctx IN OUT SECONDMAX_J)

    Return number
    IN THE JAVA LANGUAGE
    NAME "Java.Math.BigDecimal return from SecondMax_j.ODCIAggregateInitialize (oracle.sql.STRUCT []).
    ,



    Member ODCIAggregateIterate (self IN OUT SECONDMAX_J function,

    Number return value)
    IN THE JAVA LANGUAGE
    NAME "Java.Math.BigDecimal SecondMax_j.ODCIAggregateIterate return (Java.Math.BigDecimal).
    ,



    Member ODCIAggregateTerminate (self IN SECONDMAX_J function,

    Return returnValue NUMBER, flags in number number)
    IN THE JAVA LANGUAGE
    NAME "Java.Math.BigDecimal return of SecondMax_j.ODCIAggregateTerminate (double [], int).
    ,



    Member ODCIAggregateMerge (self IN OUT SECONDMAX_J function,

    CTX2 IN SECONDMAX_J) return number
    IN THE JAVA LANGUAGE
    NAME "Java.Math.BigDecimal SecondMax_j.ODCIAggregateMerge return (oracle.sql.STRUCT)".
    );
    /

    CREATE OR REPLACE FUNCTION F_SECONDMAX_J (NUMBER value) RETURN NUMBER

    PARALLEL_ENABLE

    AGGREGATION to the HELP of SecondMax_j;
    /



    When I now use the F_SECONDMAX_J function.

    "(Columnname) select F_SECONDMAX_J from Tablename t;

    It works perfectly and shows me the right result.

    Then I tried to implement the fusion part as follows:

    public BigDecimal ODCIAggregateMerge (oracle.sql.STRUCT ctx2) throws SQLException {}

    BigDecimal Key2 = null;

    BigDecimal ctx_max = null;
    BigDecimal ctx_secmax = null;

    BigDecimal ctx2_max = null;
    BigDecimal ctx2_secmax = null;

    retrieve the context stored with the key
    StoredCtx_SecMax ctx = null;
    try {}
    CTX = (StoredCtx_SecMax) ContextManager.GetContext (Key.intValue ());
    } catch (Exception e) {}

    }

    Object [] impAttr = ctx2.getAttributes ();

    Key2 = (BigDecimal) impAttr [0];

    retrieve the second context stored using the key2
    StoredCtx_SecMax ctx_sec = null;
    try {}
    ctx_sec = (StoredCtx_SecMax) ContextManager.GetContext (key2.intValue ());
    } catch (Exception e) {}

    }

    ctx_max = ctx. LeseMax();
    ctx_secmax = ctx. LeseSecMax();

    ctx2_max = ctx_sec. LeseMax();
    ctx2_secmax = ctx_sec. LeseSecMax();

    If (ctx2_max.compareTo (ctx_max) == 1)
    {
    If (ctx2_secmax.compareTo (ctx_secmax) == 1)
    {
    CTX. SchreibeSecMax (ctx2_secmax);
    }
    on the other
    {
    CTX. SchreibeSecMax (ctx_max);
    }
    CTX. SchreibeMax (ctx2_max);
    }
    on the other
    {
    If (ctx2_max.compareTo (ctx_secmax) == 1)
    {
    CTX. SchreibeSecMax (ctx2_max);
    }
    }

    return a SUCCESS;
    }

    When I now try the function

    "Select / * + parallel (t 4) * / F_SECONDMAX_J (Columnname) of Tablename t;

    I always get a pointer NULL-error because the variable key2 is always 0 and therefore the functions LeseMax() and LeseSecMax()
    in the second context 'ctx_sec' produce this error NULL pointer.

    To me it seems that each parallel process is the construction of an additional class for himself, which is not available are my main process.

    My question is now how it is possible to access the context of stored of the parallel process, so that I can combine the results.

    Thank you very much

    Josef

    Hi Josef,

    just guess that I've never implemented with java user-defined aggregate functions or support parallel execution:

    Maybe you have to implement ODCIAggregateWrapContext?

    + Application of ODCIAggregateWrapContext is optional. It should be implemented only when the external memory is used to hold the aggregative, context and the user-defined aggregate is evaluated in parallel (which is, stated as PARALLEL_ENABLE). If the user-defined aggregate is not evaluated in parallel, ODCIAggregateWrapContext is not necessary. +
    [http://docs.oracle.com/cd/B12037_01/appdev.101/b10800/dciaggfns.htm#i1004974]

    Report it to progress and success.

    Good luck
    Rainer Stenzel

  • Bug with the aggregate function and no group

    When I run the following query:
    with the_table as
    (
      select 1 as id, 100 as cost from dual
      union all select 2 as id, 200 as cost from dual
      union all select 3 as id, 300 as cost from dual
      union all select 4 as id, 400 as cost from dual
      union all select 5 as id, 500 as cost from dual
    )
    select id, cost
    from
    (
      select id, cost
      from the_table
      --
      union all
      --
      select 0 as id, sum(cost) as cost
      from the_table
      where 0 = 1
      -- group by 1
    )
    order by id;
    I get this result:
    ID    COST
    --  ------
     0  <null>     
     1     100
     2     200
     3     300
     4     400
     5     500
    However, when I "uncomment" the line "Group 1", the query works as expected (without the id = rank 0).

    This occurs even when "the_table" is an array.

    Someone else comes through this (and if so, how long is a problem)?

    The database is 11.2.0.2.0 64-bit.

    EDIT: It also happens without a Union - the following returns a single line (with null 0 and cost of id) without the Group By and no line with her:
    select id, cost
    from
    (
      select 0 as id, sum(cost) as cost
      from 
      (
        select 1 as id, 100 as cost from dual
        union all select 2 as id, 200 as cost from dual
        union all select 3 as id, 300 as cost from dual
        union all select 4 as id, 400 as cost from dual
        union all select 5 as id, 500 as cost from dual
      )
      where 0 = 1
      -- group by 1
    )
    order by id
    Edited by: Donbot February 15, 2012 10:29

    Donbot wrote:
    Someone else comes through this (and if so, how long is a problem)?

    The database is 11.2.0.2.0 64-bit.

    This is a documented behavior.

    http://docs.Oracle.com/CD/E11882_01/server.112/e26088/functions003.htm#SQLRF20035

    "
    All except COUNT (*) GROUPING and GROUPING_ID aggregate functions ignore NULL values. You can use the NVL function in the argument of an aggregation function to substitute a value for a null value. COUNTY and REGR_COUNT never return null, but return a number or zero. For all remaining functions of aggregation, * if the DataSet contains no line, * or if it contains only the rows with NULL values as arguments to the aggregate function, * then the function returns null.*
    "

  • SQL statement by using the min aggregate function result extract a line - how?

    Need help, try to do something seemingly simple. I'll give a simple example to illustrate the problem.

    I'll use a simple table of addresses with 4 fields.

    Create the table:
      CREATE TABLE "ADDRESSES" 
       (     "OWNER_NAME" VARCHAR2(20 BYTE), 
         "STREET_NAME" VARCHAR2(20 BYTE), 
         "STREET_NUMBER" NUMBER
       ) ;
    complete with 6 rows
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('FRED','MAIN',1);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JOAN','MAIN',2);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JEAN','MAIN',3);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JACK','ELM',1);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JANE','ELM',2);
    Insert into ADDRESSES (OWNER_NAME,STREET_NAME,STREET_NUMBER) values ('JEFF','ELM',3);
    We now have this:
    Select * from addresses
    OWNER_NAME           STREET_NAME          STREET_NUMBER          
    -------------------- -------------------- ---------------------- 
    FRED                 MAIN                 1                      
    JOAN                 MAIN                 2                      
    JEAN                 MAIN                 3                      
    JACK                 ELM                  1                      
    JANE                 ELM                  2                      
    JEFF                 ELM                  3                      
    
    6 rows selected
    Now, I want to group by street name and obtain a number of houses. At the same time, I would like to know the number of the first and the last House
        select
        street_name,
        count(*) "NBR HOUSES",
        min(street_number) "First Number",
        max(street_number) "Last Number"
         from addresses
        group by street_name
    
    produces
    
    STREET_NAME          NBR HOUSES             First Number           Last Number            
    -------------------- ---------------------- ---------------------- ---------------------- 
    ELM                  3                      1                      3                      
    MAIN                 3                      1                      3                      
    
    2 rows selected
    Excellent. Now for the problem. I would also like to list on each line, the owner who lives at number House first and/or the last. It should be noted, assume that the name of the street and the number is unique

    It seems I have everything that I need. Don't know how to get home.

    I tried:
    select
        street_name,
        count(*) "NBR HOUSES",
        min(street_number) "First Number",
        max(street_number) "Last Number",
        (Select b.owner_name from addresses b where b.street_number = min(street_number) and b.owner_name = owner_name) "First Owner"
         from addresses
        group by street_name
    But getting a syntax error sql group function unauthorized when I add the subselect statement.

    any ideas?

    Thanks for any help.

    Published by: user6876601 on November 19, 2009 19:08

    Published by: user6876601 on November 19, 2009 19:30

    Hello

    Welcome to the forum!

    Get the minimum and maximum number for each street is a pretty simple concept; simpler to describe and simple to code.
    Now you want to the owner_name associate the maximum and minimum, which is a concept more complex; a little more difficult to describe and, unfortunately, much less simple to code and much, much more difficult to explain:

    select
        street_name,
        count (*)                "NBR HOUSES",
        min (street_number)      "First Number",
        min (owner_name) KEEP (DENSE_RANK FIRST ORDER BY street_number)
                        "First Owner",
        max (street_number)      "Last Number",
        min (owner_name) KEEP (DENSE_RANK LAST ORDER BY street_number)
                        "Last Owner"
         from addresses
        group by street_name
    ;
    

    You will notice that I used min for "Original owner" and "last owner". Why is this?
    The key word in these functions is the FIRST or the LAST word that comes after DENSE_RANK and before ORDER BY. The function at the beginning is simply a break.

    In other words, MIN in this context refers only to what needs to happen when there is a link to the first or last in the group. Even if such a thing is impossibe in your data, generic functions must have a mechanism to return a single owner_name when two or more rows have an equal right to having the highest street_number. For example, if we change the address of Joan in 1 hand, then MIN (street_number) is always 1, of course, but who is the person associated with the minimum street_number: Fred or Joan? Both have an equal claim that he owns with the smallest address on Main Street, but aggregate functions must return a single value, so we must have a mechanism to indicate to the system, whether to return 'JOAN' or 'FRED '. In this example, I arbitrarily in the network said een of tie, the lowest name, in alphabetical order, must be returned. In this case, 'FRED' would return, "FRED" prior to "JOAN".

    Thank you for including CREATE TABLE and INSERT!

  • Why I can't use the nested aggregate function?

    Hello Experts,

    Why I can't use the nested aggregate function? There is not an ora-00979 group by error of expression.

    Oracle Database 11 g Release 11.2.0.4.0 - 64 bit Production

    Select

       SUM (BOX WHEN (KSD_CREATEDATE BETWEEN TRUNC((KSD_CREATEDATE)) AND TRUNC(MIN(KSD_CREATEDATE)) +60) THEN 1  ELSE 0 END) AS col

    DE TABLE_3_4

    GROUP BY STC_FIRMANO

    Thank you

    GROUP BY will manage the SUM function, but the MIN is used incorrectly - use another SELECTION to get it, or work with only with a single line. Otherwise, you could do WITH... get the SUM of SELECT MIN...

  • Data model with decimal point in aggregate functions

    Hello

    In the data model when a summary aggregate function type is created, the decimal fields are displayed with ',' instead of '. '.

    Is it possible to tell displayed with decimal BEEP '. '?

    I solve it by copying the CS attribute and create a new by an element of expresion.

  • Pivot table result without aggregate function

    Hi all

    We have the following two tables:

    SQL > select * from class;

    CLASS_ID COURSES

    ---------- ----------

    1          1

    2          1

    3          1

    2          2

    3          2

    5          2

    6 selected lines.

    SQL > select * of course.

    COURSE_ID

    ----------

    1

    2

    The customer needs the output in the following format:

    class class class class

    1                    1               2               3

    2                    2               3               5

    I considered using the operator pivot tables however they require the use of an aggregate function, but there is no aggregation only required in the result here - we demand that the output as would a PivotTable?

    Try this.

    WITH class(CLASS_ID,COURSE) AS)

    1.1 DOUBLE UNION ALL SELECT

    SELECT 2.1 DUAL UNION ALL

    SELECT 3.1 FROM DUAL UNION ALL

    SELECT 2.2 DUAL UNION ALL

    3.2 DUAL UNION ALL SELECT

    SELECT DOUBLE 5.2)

    SELECT * FROM)

    SELECT THE COURSE

    CLASS_ID,

    ROW_NUMBER () OVER(PARTITION BY COURSE ORDER BY COURSE) RN

    CLASS)

    PIVOT (MAX (CLASS_ID) for (RN) IN (1 as CLASS1, 2 AS CLASS2, CLASS3 AS 3));

    OUTPUT:

    CLASS CLASS1 CLASS2 CLASS3

    -------- ---------- ---------- ----------

    1          1          2          3

    2          2          3          5

  • Aggregate functions

    Why aggregate (sum, min) function returns a line (with a null value) even though my there is no lines satisfying the where clause. Pls find the below example

    Select 1 from scott.emp where deptno = 1,011 - no row returned

    Select sum (sal) in the scott.emp where deptno = 1,011 - returns a row with null as a value. The thing is that if there are no rows in the emp table with a floating point number of employee. (Sum) should not have been called.

    Here's how that works:

    http://docs.Oracle.com/CD/E11882_01/server.112/e26088/functions003.htm

    All functions except aggregation COUNT (*), GROUPING , and GROUPING_ID ignore NULL values. You can use the NVL function in the argument of an aggregation function to substitute a value for a null value COUNT and REGR_COUNT never return null, but returns a number or zero. For all the remaining functions of aggregation, If the DataSet has no rows, or contains only rows with NULL values as arguments to the aggregate function, then the function returns the value null.

  • Problem with my aggregate function

    Hello

    I tried to build my own global function in the chain, but I have a problem when I use it in my application. When I'm with her, he wrote ORA904, considering that this idenfifier exists. Do you know what is the problem?

    here my aggregate function:
    create or replace FUNCTION aggme (query_in in VARCHAR2) RETURN VARCHAR2 IS
        incoming    varchar2(4000);
        hold_result varchar2(4000);
        c sys_refcursor;
    Begin
        open c for query_in;
        loop
            fetch c into incoming;
            exit when c%notfound;
            hold_result := hold_result||','||incoming;
        end loop;
        return ltrim(hold_result,',');
    END;
    and here my request using my aggregate function aggme:
    select
      RES.LASTNAME as "LASTNAME",
      RES.FIRSTNAME as "FIRSTNAME",
      aggme('select NAME from PATHOLOGY where ID= RES.PATHOLOGY_ID') as "PATHOLOGY"
    from
      TBK_RESOURCE RES

    user539451 wrote:
    Hi BluShadow,

    I followed your advice and try to use the aggregation of clob. No problem to compile the function but when I use the clobagg to my query, is not aggregated. Perhaps, I don't use it correctly.

    select
    RES.PATIENT_LASTNAME as "LASTNAME",
    RES.PATIENT_FIRSTNAME as "FIRSTNAME",
    (select trim(',' from clobagg(name||',')) as "pathology" from pathology where ID= RES.PATHOLOGY_ID)
    FROM
    TBK_RESOURCE RES
    

    output, I have:

    FIRSTNAME. LASTNAME. PATHOLOGY
    TOTO | OTOT | ACB
    TOTO | OTOT | GB

    instead of having:
    TOTO OTOT ACB, GB

    Well, I don't have data to work with, but it works well for me...

    SQL> ed
    Wrote file afiedt.buf
    
      1  with t as (select 'TOTO' as FIRSTNAME, 'OTOT' as LASTNAME, 'PBR' as PATHOLOGY from dual union all
      2             select 'TOTO', 'OTOT', 'GB' from dual)
      3  --
      4  -- end of test data
      5  --
      6  select firstname, lastname
      7        ,trim(',' from clobagg(pathology||',')) as pathology
      8  from t
      9* group by firstname, lastname
    SQL> /
    
    FIRS LAST PATHOLOGY
    ---- ---- --------------------------------------------------------------------------------
    TOTO OTOT PBR,GB
    
  • Performance of the aggregate function.

    Hello

    Version 11.2.0 Oracle

    I'm not a PL/SQL Developer, however, I decided to write this aggregate out function. Oracle has it but I tried TimesTen database in memory that does not yet function stddev.

    The code is as follows:
    CREATE OR REPLACE TYPE MyStddevImpl AS OBJECT
    (
      v_power NUMBER, -- sum(power^2) of the column
      v_sum   NUMBER, -- average value
      v_iteration NUMBER, -- count(1)
    
      STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT MyStddevImpl)
        RETURN number,
    
      MEMBER FUNCTION ODCIAggregateIterate(self IN OUT MyStddevImpl,
        value IN number)
        RETURN number,
    
      MEMBER FUNCTION ODCIAggregateTerminate(self IN MyStddevImpl,
        returnValue OUT number, flags IN number)
        RETURN number,
    
      MEMBER FUNCTION ODCIAggregateMerge(self IN OUT MyStddevImpl,
       ctx2 IN MyStddevImpl)
       RETURN number
    );
    /
    show error
    
    CREATE OR REPLACE TYPE BODY MyStddevImpl
    AS
    STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT MyStddevImpl)
    RETURN number
    AS
    BEGIN
      sctx := MyStddevImpl(0,0,0);
      RETURN ODCIConst.Success;
    END;
    
    MEMBER FUNCTION ODCIAggregateIterate(self IN OUT MyStddevImpl, value IN number)
    RETURN number
    AS
    BEGIN
      self.v_sum   := self.v_sum + value;   -- used to get averages
      self.v_power := self.v_power + power(value,2);
      self.v_iteration := self.v_iteration + 1;  -- total  number of rows
      return ODCIConst.Success;
    END;
    
    MEMBER FUNCTION ODCIAggregateTerminate(self IN MyStddevImpl, returnValue OUT
                                           number, flags IN number)
    RETURN number
    AS
      v_avg number;
    BEGIN
      v_avg :=  self.v_sum/self.v_iteration;   -- this is the average value
       -- sqrt((sum(power(amount_sold,2))-(count(1)*power(avg(amount_sold),2)))/(count(1)-1))
      returnValue := sqrt((self.v_power - (self.v_iteration * power(v_avg,2))) /(self.v_iteration-1));
      RETURN ODCIConst.Success;
    EXCEPTION
      WHEN VALUE_ERROR
      THEN
        RETURN ODCIConst.error;
    END;
    
    MEMBER FUNCTION ODCIAggregateMerge(self IN OUT MyStddevImpl, ctx2 IN
    MyStddevImpl)
    RETURN number
    AS
    BEGIN
     RETURN ODCIConst.Success;
    END;
    END;
    /
    show error
    CREATE OR REPLACE FUNCTION MyStddev (input NUMBER)
    RETURN number
    AGGREGATE USING MyStddevImpl;
    /
    show error
    exit
    Now, it works very well and returns the results OK.
    select mystddev(amount_sold) AS "My standard deviation", stddev(amount_sold) from sales;
    
    My standard deviation STDDEV(AMOUNT_SOLD)
    --------------------- -------------------
                259.78049           259.78049
    The problem I have is that it takes 10.5 sec to run
     select mystddev(amount_sold) from ssdtester.sales;
    
    MYSTDDEV(AMOUNT_SOLD)
    ---------------------
               273.172955
    
    Elapsed: 00:00:10.48
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1047182207
    
    ----------------------------------------------------------------------------
    | Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |       |     1 |     5 |  1324   (1)| 00:00:16 |
    |   1 |  SORT AGGREGATE    |       |     1 |     5 |            |          |
    |   2 |   TABLE ACCESS FULL| SALES |  1000K|  4882K|  1324   (1)| 00:00:16 |
    ----------------------------------------------------------------------------
    
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
           4965  consistent gets
              0  physical reads
              0  redo size
            558  bytes sent via SQL*Net to client
            524  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    Is there any scope to improve this code. Specifically can I use avg function in the code instead of working on myself?

    Thank you

    Mich

    Published by: Mich Talebzadeh on February 13, 2012 12:20

    >
    May I ask what is the purpose of the model of aggregate by Oracle functions if it will be row-by-row and he's not going to be effective.
    >
    Oracle online the way you did in your function.

    Your function, using the technology of data cartridges, will be called by Oracle for EACH LINE it reads each line corresponding to your query. This requires a change in context of SQL, PL/SQL, and then back to SQL. It is a very expensive operation in terms of time.

    The Oracle SQL engine is not that way for aggregate functions it provides. The functionality of data cartridge is provided to allow developers to extend Oracle to provide features that Oracle is not provde all. Use of these functions of cartridge cases, you develop may not be 'slow' because there is no equivalent Oracle to compare to. You can use the features of your new cartridge or do you without; you have no other choice.

    You should always use SQL from Oracle to do the job unless you are doing something that can be done in SQL. Then you should use of Oracle PL/SQL features (for example in BULK of treatment) to do the more complex things. Finally if you need to do something just that Oracle cannot do with out-of-the-box SQL or PL/SQL, then you turn cartridge data, custom Java or C code or other external solutions which you can interface to Oracle.

    The order of the solutions, you should look at is:
    1 SQL
    2 PL/SQL
    3 Java/C external
    4 data cartridge

    He explains a little better? (and it is frankly win again in a minute or two!)

  • analytical function and the aggregate function

    What are the analytical function and the aggregate function. What is the difference between them?

    Hello

    Analytic Functions : -.

    Analytical functions calculate a value of aggregation based on a group of lines. They differ from aggregate functions because they return several rows for each group. The Group of rows is called a window and is defined by the analytic_clause. For each line, a sliding window of lines is defined. The window determines the range of lines used for the calculations for the current line. Window sizes can be based on a physical number of rows or a logic as the time interval.
    Analytical functions are the last set of operations performed in a query with the exception of the last ORDER BY clause. Every joint and every WHERE, GROUP BY and HAVING clauses are met before the analytical functions are handled. As a result, analytic functions can only appear in the select list or the ORDER BY clause.
    Analytical functions are commonly used to calculate cumulative aggregates, moving, centered and considered.

    Aggregate functions : -.

    Aggregate functions return a line of single result based on the groups of lines, rather than on the unique lines. Aggregate functions can appear in selection lists, as well as in the HAVING and ORDER BY clauses. They are commonly used with the GROUP BY clause in a SELECT statement, where Oracle Database splits the rows in a table when asked or seen in groups. In a query that contains a GROUP BY clause, the select list items can be aggregation functions, GROUP BY constant expressions or expressions involving one of them. Oracle applies the functions of aggregation for each group of rows and returns a single result for each group line.
    If you omit the GROUP BY clause, Oracle then applies any aggregate functions in the select list for all rows in the table queried or the view. You use aggregate functions in the HAVING clause to eliminate groups of the output based on the results of aggregate functions, rather than the values of the individual lines of the queried table or view.

    Let me know if you feel any problem understanding.
    Thank you.

    Published by: varun4dba on January 27, 2011 15:32

  • How to include an aggregate function in a function user_defined

    I created the following function to validate the value of the commission of a table I created



    create or replace function validate_comm (number v_comm)
    return a Boolean value
    is
    VCOMM employeesCopy.commission_pct%type;
    Start
    Select max (commission_pct) in vcomm
    of employeesCopy
    where commission_pct = v_comm;
    If v_comm < vcomm then
    Returns true;
    on the other
    Returns false;
    end if;
    end;



    the service was created successfully, but when I run it as follows:



    Start
    If validate_comm (0.0) then
    dbms_output.put_line ('True');
    on the other
    dbms_output.put_line ('False');
    end if;
    end;



    He always gives the wrong data, even if the maximum value of commission_pct in my table is 0.4 but I always wrong whenever I run the function. Why? and is it true to put the aggregate function in the select statement?

    Hello

    If you don't want to UPDATE to each row of the table, and then add a WHERE clause to your UPDATE statement.

    You can do what you want without procedures or user-defined functions:

    update      employeesCopy
    set      commission_pct      = v_comm;
    where     commission_pct     < (
                        SELECT     MAX (commission_pct)
                        FROM     employeesCopy
                     );
    

    You didn't post a test version of your table, so I can't really test this.

    There are good reasons to want to do this in PL/SQL. If you have one, you can write a procedure reset_comm that executes the UPDATE above statement.
    If you want to make the statement to UPDATE a bit simpler by writing a function defined by the user (even if the net result is more coding and complexity more) so I think that a function takes no arguments and returning the MAX (commission_pct) would be more useful than something that had a fight and has returned a value depending on whether the qualified argument one line update , but if you don't want such a function, its arguments must be the values to take into account when it decides whether a line is updated. Should what value (s) on each line you consider in deciding if this line is up to date? If it's just commission_pct, then your procedure reset_comm might look like this:

    create or replace procedure reset_comm (v_comm number)
    is
    begin
         update      employeesCopy
         set      commission_pct = v_comm;
         where     validate_comm (commission_pct)     = 'OK';
    end;
    
  • Aggregate function with joining

    Hi all
    I have the following SQL query, and I want to add a join with it:
    SELECT Collected_Goods.ProductId, SUM(Collected_Goods.Amount)
    FROM Collected_Goods
    GROUP BY Collected_Goods.ProductId
    and I want to replace or add (but it is better to replace) the Collected_Goods. ProductId with a product. Name where the product name is displayed in another table called products. I also want the SUM aggregate function to work on Collected_Goods.ProductId

    FK in Collected_Goods to the products is Collected_Goods.ProductId and Products.Id

    Thanks in advance

    Published by: ZiKaS on December 30, 2008 02:05

    Oops then try like this

    SELECT c.ProductId, p.Name, SUM(c.Amount)
      FROM Collected_Goods c
      JOIN Products p
        ON c.ProductId = p.ProductId
     GROUP BY c.ProductId, p.name
    
  • Question of rank of analytic function

    Hi all

    Table with 2 columns table_name and category_name below. I want to give a sequence to a category, whenever the new category is found when the data is sorted by table_name and category_name.

    Sample data is

    create of the table xx_test_rank (table_name varchar2 (20), category_name varchar2 (40));

    insert into xx_test_rank values (' 1 ',' Delivery ');

    insert into xx_test_rank values (' 1 ',' Go Live ');

    insert into xx_test_rank values (' 1 ',' Support delivery ");

    insert into xx_test_rank values (' 1 ',' Support delivery ");

    insert into xx_test_rank values (' 2.B ',' Delivery ');

    insert into xx_test_rank values (' 2.B ',' Services ');

    insert into xx_test_rank values (' 2.B ',' Support delivery ");

    insert into xx_test_rank values (' 3.C ',' Completion ');

    insert into xx_test_rank values (' 3.C ',' Delivery ');

    insert into xx_test_rank values (' 4.D ',' Go Live ');

    insert into xx_test_rank values (' 4.D ',' Support delivery ");

    commit;

    If I write in request, category of benefit table 2.B shows new sequence. But I want him to have 1.

    SELECT table_name, category_name,

    DENSE_RANK () OVER (ORDER BY table_name, category_name) rk

    OF xx_test_rank

    ORDER BY table_name, category_name

    Please help me how I can get my result except in SQL.

    TableCategoryDense rankEXPECTED rank
    1.ADelivery11
    1.AGo live22
    1.ASupport delivery33
    1.ASupport delivery33
    2.BDelivery41
    2.BServices54
    2.BSupport delivery63
    3.CEnd75
    3.CDelivery81
    4.DGo live92
    4.DSupport delivery103

    Thank you
    Kishore

    Hi, Kishore,

    Interesting problem!

    Here's one way:

    WITH got_rk AS

    (

    SELECT table_name, category_name

    DENSE_RANK () OVER (ORDER BY table_name

    category_name

    ) AS rk

    OF xx_test_rank

    )

    got_min_rk AS

    (

    SELECT table_name, category_name, rk

    , MIN (rk) OVER (PARTITION BY category_name) AS min_rk

    OF got_rk

    )

    SELECT table_name, category_name, rk

    DENSE_RANK () OVER (ORDER BY min_rk) AS expected_rank

    OF got_min_rk

    ORDER BY table_name, category_name

    ;

    I wonder if there is a way to do it with 1 single subquery.  I'll post again if I think of a better way.

    Thanks for posting the CREATE TABLE and INSERT statements; It is very useful.

Maybe you are looking for