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

Tags: Java

Similar Questions

  • 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

  • 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...

  • 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

  • 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.

  • Based where conditional clause...

    dear team,
    i have following code..
    
    Declare
      gv_flag1 Varchar2(1)   := 'N';
      gv_flag2 Varchar2(1)   := 'N';
      gv_flag3 Varchar2(1)   := 'N';
      all_where1       Varchar2(250);
      all_where2       Varchar2(250);
      ALL_where3       Varchar2(250);
      V_QTY           Number;
    Begin
      If gv_flag1 = 'N' Then
         all_where1 := 'AND '||'V.OWNER = ''PROD''';
      End If;
      DBMS_OUTPUT.PUT_LINE(all_where1);
      
      If gv_flag2 = 'N' Then 
         all_where2 := 'AND '||'V.OPERATION NOT LIKE (''10%'')';
      End If;   
      DBMS_OUTPUT.PUT_LINE(all_where2);
      
      If gv_flag3 = 'N' Then
         all_where3 := 'AND '||'V.OPERATION NOT LIKE (''07%'')';
      End If;
      DBMS_OUTPUT.PUT_LINE(all_where3); 
       
      --select based on conditions..
    End; 
    
    NOW I want where conditions in select statment to be conditional...
    
    which means if flag1='N' and flag2 = 'N' then use both all_where1 and all_where2 in *where* clause statement...
    if flag1='N' and flag3 = 'N' then then use all_where1 and all_where 3 in *where* clause of select statement...
    if all there flag = 'N' then use all_where conditions in *where* clause of select statement...
    
    i have 3 flags, which means total of 9 combinations,  is there any simpler way to do such kind of thing??
    
    please assist me
    
    nic

    Nicloei W wrote:
    Hi Jeenesh,

    What happens if Flag2 = 'Y' and Indicateur3 = 'Y' in this case, I want only the condition with Flag1

    concerning
    NIC

    SQL> ed
    Wrote file afiedt.buf
    
      1  Declare
      2    gv_flag1 Varchar2(1)   := 'N';
      3    gv_flag2 Varchar2(1)   := 'Y';
      4    gv_flag3 Varchar2(1)   := 'Y';
      5    --all_where1       Varchar2(250);
      6    --all_where2       Varchar2(250);
      7    --ALL_where3       Varchar2(250);
      8    lc_query varchar2(1000):= 'select count(*) from test v ';
      9    lc_where varchar2(500) := ' where 1 = 1 ';
     10    V_QTY           Number;
     11  Begin
     12    If gv_flag1 = 'N' Then
     13       lc_where := lc_where||' AND V.OWNER = ''TEST''';
     14    End If;
     15    If gv_flag2 = 'N' Then
     16       lc_where := lc_where||' AND V.OPERATION NOT LIKE ''10%''';
     17    End If;
     18    If gv_flag3 = 'N' Then
     19       lc_where := lc_where||' AND V.OPERATION NOT LIKE ''07%''';
     20    End If;
     21    lc_query := lc_query||lc_where;
     22    dbms_output.put_line(lc_query);
     23    dbms_output.put_line('-----------');
     24    execute immediate lc_query into v_qty;
     25    dbms_output.put_line('Count: '||v_qty);
     26* End;
    SQL> /
    select count(*) from test v  where 1 = 1  AND V.OWNER = 'TEST'
    -----------
    Count: 3
    
    PL/SQL procedure successfully completed.
    
  • 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
    
  • 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.*
    "

  • 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!)

  • 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;
    
  • 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!

  • 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
    

Maybe you are looking for

  • Cannot open the initial window of Firefox. (windows7 update)

    When I run Firefox, the hourglass shows seconds, then disappears.No window is open. This occurs after an automated update to myWindows overnight Tuesday, dec 9. Internet Explorer is obviously OK.All other programs OK. Have tried - without change: res

  • Update Firefox causing 34,05 of sites to load as lists

    Since upgrading to Firefox 34 then 34,05 some sites, ones that I use most, load a list. It comes to great sites and load perfectly fine in IE. This is causing me problems without end and makes me think that these improvements are just an exercise in

  • Firefox incorrectly identifies .xlsx attachments as documents HTML Firefox

    When I try to open attachments with .xlsx file extensions, Firefox identifies as a document HTML Firefox and the "open a file" window shows not Excel in option - when I try to go to Excel, the window only opens 'my programs' where I might be able to

  • ATI Radeon HD 5570 woes...

    Recently got a HPE-360z handed to nine with a graphics ATI 5570 2G card. Using this with a 24 "or 46" 1920 x 1080 HD monitor/TV. Crisp image of lack - pictures are grainy or washed out. Text and video are blurred. Connection of a netbook with an Inte

  • HP ENVY m6 n010dx: HP ENVY m6 n010dx stuck on the loading screen

    I have another problem with my computer hp laptop. I'll give some general information, before I started having this problem. I was on my laptop, watching my email. I went to open a new tab and typed in "youtube.com" and the page will not load. After