Analytic function

Dear masters,

Oracle version: 11.2.0.2.0

I have a table called price_detail where the data is there in the format below

Sell_date(mm/dd/yyyy)

Dealer_Price

Discount

Net price

Net_Price_before_discount

01/01/2013

100

10

02/01/2013

120

20

03/01/2013

200

10

04/01/2013

100

20

05/01/2013

120

10

06/01/2013

210

30

07/01/2013

140

40

08/01/2013

150

10

09/01/2013

200

20

10/01/2013

100

10

11/01/2013

120

30

12/01/2013

140

20

In my program, I am passing a date range (for this example say entry date between 04/01/2013 09/01/2013), I need to calculate the NET_PRICE and the NET_PRICE_BEFORE_DISCOUNT for a given date range

Sell_date(mm/dd/yyyy)

Dealer_Price

Discount

Net price

Net_Price_before_discount

01/01/2013

100

10

02/01/2013

120

20

03/01/2013

200

10

04/01/2013

100

20

70

100

05/01/2013

120

10

80

190

06/01/2013

210

30

200

70

07/01/2013

140

40

120

80

08/01/2013

150

10

140

200

09/01/2013

200

20

170

120

10/01/2013

100

10

11/01/2013

120

30

12/01/2013

140

20

Net = Dealer_price - Discount price (of the 3rd day after the date of the day, so if we are calculating for 04/01/2013 then delivery must come from 06/01/2013)

Net_ Price_ before_ discount = Dealer_price (of the 3rd day before the current day, so if we are calculating for 04/01/2013 then the Dealer_price must come from 02/01/2013) - Discount

I can achieve this LEAD and functions LAG problem I'm facing is that I need to calculate it only for a date range and some values (as shown above) fall not going so here it is coming as 0.

  1. for example when I am Net_price calculation for the 09/01/2013, the discount is from 11/01/2013, but as in my case clause I have a widow who allows me to get data only between 01/04/2013 and on 09/01/2013, the discount is coming up as 0.

It's really complicated for me to achieve.

Please suggest.

AB

Every time that you give examples of data give as CREATE TABLE and INSERT QUERIES or the WITH clause. Its easy when its this way rather than the data in a structure of table posted by you.

You can use LEAD and LAG function like that. You must specify the OFFSET value to meet your need.

with t

as

(

Select to_date (' 01 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 100, 10 double discount

Union of all the

Select to_date (' 02 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 120, 20 double reduction

Union of all the

Select to_date (' 03 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 200, 10 double discount

Union of all the

Select to_date (' 04 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 100, 20 double reduction

Union of all the

Select to_date (' 05 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 120, 10 double discount

Union of all the

Select to_date (' 06 / 01/2013 ', ' dd/mm/yyyy') sell_date, 210 dealer_price, 30 double discount

Union of all the

Select to_date (' 07 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 140, 40 double reduction

Union of all the

Select to_date (' 08 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 150, 10 double discount

Union of all the

Select to_date (' 09 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 200, 20 double reduction

Union of all the

Select to_date (' 10 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 100, 10 double discount

Union of all the

Select to_date (' 11 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 120, 30 double discount

Union of all the

Select to_date (' 12 / 01/2013 ', ' dd/mm/yyyy') sell_date, dealer_price 140, 20 double reduction

)

Select sell_date

dealer_price

discount

, case when sell_date between to_date (' ' 04 / 01/2013 ', ' dd/mm/yyyy ') and

TO_DATE (' 09 / 01/2013 ', ' dd/mm/yyyy "")

then dealer_price - lead (2 discount) (sell_date order)

Another null

end net_price

, case when sell_date between to_date (' ' 04 / 01/2013 ', ' dd/mm/yyyy ') and

TO_DATE (' 09 / 01/2013 ', ' dd/mm/yyyy "")

then lag (dealer_price, 2) during delivery (order of sell_date).

Another null

end net_price_before_discount

t;

Output...

SELL_DATE DEALER_PRICE NET_PRICE NET_PRICE_BEFORE_DISCOUNT DISCOUNT

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

1ST JANUARY 13 100 10

2 JANUARY 13 120 20

3 JANUARY 13 200 10

4 JANUARY 13 100 20 70 100

5 JANUARY 13 120 10 80 190

6 JANUARY 13 210 30 200 70

7 JANUARY 13 140 40 120 80

8 JANUARY 13 150 10 140 200

9 JANUARY 13 200 20 170 120

10 JANUARY 13 100 10

11 JANUARY 13 120 30

JANUARY 12, 13 140 20

12 selected lines

Tags: Database

Similar Questions

  • Cannot use analytical functions such as lag/lead in odi components 12 c except in the expression

    Hi I am a beginner of ODI 12 c

    I'm trying to get the last two comments made on the product for a given product id. and load them into a target.

    I have a source table something like

    Product SR_NO comments LAST_UPDATED_TS

    1 good car 2015/05/15 08:30:25

    1 car average 2015/05/15 10:30:25

    Jeep 2 super 2015/05/15 11:30:25

    1 car bad 2015/05/15 11:30:25

    Jeep 2 horrible 2015/05/15 09:30:25

    Jeep 2 excellent 2015/05/15 12:30:25


    I want a target table based on their last timestamp updated as (last two comments)


    SR_NO Comment1 Comment2

    1                             bad                      average

    2 super excellent

    I used the logic below to get records in SQL Developer but in ODI 12 c, I'm not able to do this by mapping a source to the target table by applying analytical functions to the columns in the target table. Can someone help me solve this problem

    SELECT * FROM)

    SELECT SR_NO Comment1, LAG(Comment1,1,) ON Comment2 (SR_NO ORDER BY LAST_UPDATED_TS ASC PARTITION),

    ROW_NUMBER() ON RN (SCORE FROM SR_NO ORDER BY LAST_UPDATED_TS DESC)

    FROM Source_table

    ) M

    WHERE RN = 1

    ;

    UM, I'm afraid that ODI puts the filter too early in the request, if it generates:

    SELECT * FROM)

    SELECT SR_NO Comment1, LAG(Comment1,1,) ON Comment2 (SR_NO ORDER BY LAST_UPDATED_TS ASC PARTITION),

    ROW_NUMBER() ON RN (SCORE FROM SR_NO ORDER BY LAST_UPDATED_TS DESC)

    FROM Source_table

    WHERE RN = 1

    ) M

    ;

    Instead of:

    SELECT * FROM)

    SELECT SR_NO Comment1, LAG(Comment1,1,) ON Comment2 (SR_NO ORDER BY LAST_UPDATED_TS ASC PARTITION),

    ROW_NUMBER() ON RN (SCORE FROM SR_NO ORDER BY LAST_UPDATED_TS DESC)

    FROM Source_table

    ) M

    WHERE RN = 1

    ;

    Even by changing the 'run on Hint"of your component of the expression to get there on the source, the request will stay the same.

    I think the easiest solution for you is to put everything before the filter in a reusable mapping with a signature of output. Then drag this reusable in your mapping as the new source and check the box "subselect enabled."

    Your final mapping should look like this:

    It will be useful.

    Kind regards

    JeromeFr

  • Which analytical function to use?


    Hi gurus,

    DB - Oracle 11 g 2

    I followed the examples of data in the table test_a.

    col1 col2 col3

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

    x                 y                   y

    p                 q                  y

    a                b                   y

    p                q                   y

    t                 r                    y

    p                q                   y

    The col3 column is always 'y '. But here's the data p, q, there is repeated 3 times (duplicate) and if this is the case I want to update only the first recordings like "n" col3 it is to say p, q, n. rest will be as it is.

    I am able to get the row_number() for it but not able to do this.

    Select col1, clo2, clo3 row_number() over (partition by col2) arrested by col1 as test_a r_num

    Would it be possible directly by any analytic function?

    Thank you

    SID

    COL4 is logical...

    Something like that?

    with x as)

    Select col1, col2 ' x' 'y', 'y' col3 col4 1 Union double all the

    Select 'p' col1, col2 'q', 'y' col3 col4 2 Union double all the

    Select 'a' col1, col2 'b', 'y' col3 col4 3 of all the double union

    Select 'p' col1, col2 'q', 'y' col3 col4 4 Union double all the

    Select 't' col1, col2 'r', 'y' col3, col4 5 Union double all the

    Select 'p' col1, col2 'q', 'y' col3 col4 6 double

    )

    ---

    Select * from)

    Select x.*,

    ROW_NUMBER() on rn1 (score of col1, col2, col3 col4 sort),

    ROW_NUMBER() on rn2 (partition by col1, col2, col3 col4 desc sorting)

    x

    )

    where rn1 = 1 and rn2 <> 1;

    Understand the logic and simply change SELECT a query to UPDATE...

  • Using the analytic function

    Oracle 11g Release 2

    I'm assuming that the best solution is the use of analytical functions.

    create table test3
    ( part_type_id  varchar2(50)
    ,group_id      number
    ,part_desc_id  number
    ,part_cmt      varchar2(50)
    )
    /
    
    insert into test3 values( 'ABC123',1,10,'comment1');
    insert into test3 values( 'ABC123',1,10,'comment2');
    insert into test3 values( 'ABC123',2,15,'comment1');
    insert into test3 values( 'ABC123',2,15,'comment2');
    insert into test3 values( 'EFG123',25,75,'comment3');
    insert into test3 values( 'EFG123',25,75,'comment4');
    insert into test3 values( 'EFG123',25,75,'comment5');
    insert into test3 values( 'XYZ123',1,10,'comment6');
    insert into test3 values( 'XYZ123',2,15,'comment7');
    commit;
    
    select * from test3;
    
    PART_TYPE_ID           GROUP_ID PART_DESC_ID PART_CMT
    -------------------- ---------- ------------ --------------------
    ABC123                        1           10 comment1
    ABC123                        1           10 comment2
    ABC123                        2           15 comment1
    ABC123                        2           15 comment2
    EDG123                        25          75 comment3
    EDG123                        25          75 comment4
    EDG123                        25          75 comment5
    XYZ123                        1           10 comment6
    XYZ123                        2           15 comment7
    
    9 rows selected.
    
    Desired output:
    
    PART_TYPE_ID           GROUP_ID PART_DESC_ID PART_CMT
    -------------------- ---------- ------------ --------------------
    ABC123                        1           10 comment1 
    ABC123                        2           15 comment1
    XYZ123                        1           10 comment1
    XYZ123                        2           15 comment2
    
    RULE: where one part_type_id has multiple (2 or more distinct combinations) of group_id/part_desc_id
    
    NOTE: There are about 12 columns in the table, for brevity I only included 4.
    
    
    
    

    Post edited by: orclrunner was updated desired output and rule

    Hello

    Here's one way:

    WITH got_d_count AS

    (

    SELECT part_type_id, group_id, part_desc_id

    MIN (part_cmt) AS min_part_cmt

    COUNT AS d_count (*) OVER (PARTITION BY part_type_id)

    OF test3

    GROUP BY part_type_id, group_id, part_desc_id

    )

    SELECT DISTINCT

    group_id, part_desc_id, part_type_id, min_part_cmt

    OF got_d_count

    WHERE d_count > 1

    ;

    Output:

    GROUP_ID PART_DESC_ID MIN_PART_CMT PART_TYPE_ID

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

    ABC123 1 10 comment1

    ABC123 2 15 comment1

    XYZ123 1 10 comment6

    XYZ123 2 15 comment7

    Analytical functions, such as the COUNTY and MIN, many global versions, in addition, it can give the same results.  Use the analytical versions when each row of output corresponds to exactly 1 row of input and the aggregate and GROUP BY version when each line of output corresponds to a group of lines 1 or more input.  In this issue, each line of output appears to be a group of input lines having the same group_id, part_type_id, and part_desc_id (I'm guessing just, this only has never stated), so I used GROUP BY to get 1 row of output for every input lines.

  • Truncate output of analytical function?

    For example this query:

    Select month, sum (tot_sales) monthly_sales,.

    AVG (Sum (tot_sales)) (any order by month

    between 1 above and 1 below) rolling_avg

    orders

    where year = 2001 and region_id = 6

    Group by month;

    gives me an output which includes several decimal places for the rolling_avg column.

    Is there a way to truncate this? I tried to use the rounded outside the analytical function and surely enough, it didn't work. I can't think otherwise.

    You can use an external selection on the result of this query

    select trunc(rolling_avg) from
    ( rolling_avg query);
    
  • Nth salary using the analytic function

    I use under function to calculate second highest with empno and deptno salary.

    Is it possible to get the same result with another query without using Assembly only analytical functions condition.using and windows function is possible to get the desired output?

    SELECT e.empno,

    e.DEPTNO,

    tmp. SAL as second_higher_salary

    FROM emp e,.

    (SELECT Empno,

    DEPTNO,

    SAL,

    DENSE_RANK() (PARTITION BY deptno ORDER of sal) AS rnk

    WCP

    ) tmp

    WHERE tmp.deptno = e.deptno

    and tmp.rnk = 2

    EMPNO DEPTNO SAL

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

    7934 10 2450

    7782 10 2450

    7839 10 2450

    7876 20 1100

    7369 20 1100

    7902 20 1100

    7788 20 1100

    7566 20 1100

    7900 30 1250

    7844 30 1250

    7654 30 1250

    7521 30 1250

    7499 30 1250

    7698 30 1250

    7900 30 1250

    7844 30 1250

    7654 30 1250

    7521 30 1250

    7499 30 1250

    7698 30 1250

    Here's my solution:

    Select empno,

    DEPTNO,

    FIRST_VALUE (sal) (PARTITION BY deptno ORDER by sal desc)

    de)

    SELECT EmpNo,

    DEPTNO,

    Decode (DENSE_RANK () OVER (PARTITION BY deptno order by sal desc), 1,-sal, sal) sal

    WCP

    )

    /

    EMPNO DEPTNO FIRST_VALUE (SAL) OVER (PARTITIONBYDEPTNOORDERBYSALDESC)

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

      7782 10 2450
      7934 10 2450
      7839 10 2450
      7566 20 2975
      7876 20 2975
      7369 20 2975
      7788 20 2975
      7902 20 2975
      7499 30 1600
      7844 30 1600
      7654 30 1600
      7521 30 1600
      7900 30 1600
      7698 30 1600
  • Why the different values for an analytic function of the same group/game

    I have the suite of table I'll be using.

    Select * from table1;

    REC_ID | STATUS | DATE_FROM | DATE_TO

    1. C | 7 January 2015 |

    2. H | December 3, 2014. 6 January 2015

    3. H | October 3, 2014. December 2, 2014

    4. H | May 30, 2014. October 2, 2014

    5. H | May 29, 2014 | May 29, 2014

    6. H | April 16, 2014 | May 28, 2014

    7. H | Tuesday, April 25, 2007 April 15, 2014

    INSERT statement if you need.

    TOGETHER TO DEFINE

    CREATE THE TABLE1 TABLE:

    (

    NUMBER OF REC_ID,

    VARCHAR2 (1 BYTE) STATUS NOT NULL,.

    DATE_FROM DATE NOT NULL,

    DATE OF DATE_TO

    );

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM)

    Values

    (1, 'C', TO_DATE (7 JANUARY 2015 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (2, 'H', TO_DATE (3 DECEMBER 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (6 JANUARY 2015 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (3, 'H', TO_DATE (3 OCTOBER 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (2 DECEMBER 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (4, 'H', TO_DATE (MAY 30, 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (2 OCTOBER 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (5, 'H', TO_DATE (29 MAY 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (29 MAY 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (6, 'H', TO_DATE (APRIL 16, 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (28 MAY 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    Insert into TABLE1

    (REC_ID, STATUS, DATE_FROM, DATE_TO)

    Values

    (7, 'H', TO_DATE (APRIL 25, 2007 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'), TO_DATE (APRIL 15, 2014 00:00:00 ',' DD/MM/YYYY HH24:MI:SS'));))

    COMMIT;

    I will exercise more analytical query...

    Select rec_id date_from, date_to, status,

    min (date_from) over (partition by order of status by date_from desc) min_dt_from_grp,

    ROW_NUMBER() over (partition by order of status by date_from desc) rownumberdesc,

    ROW_NUMBER() over (partition by order of status by ASC date_from) rownumberasc

    FROM table1;

    the query result

    REC_ID | DATE_FROM | DATE_TO | STATUS | MIN_DT_FROM_GRP | ROWNUMBERDESC | ROWNUMBERASC

    1. 7 January 2015 | C | 7 January 2015 | 1. 1

    2. December 3, 2014. 6 January 2015 | H | December 3, 2014. 1. 6

    3. October 3, 2014. December 2, 2014 | H | October 3, 2014. 2. 5

    4. May 30, 2014. October 2, 2014 | H | May 30, 2014. 3. 4

    5. May 29, 2014 | May 29, 2014 | H | May 29, 2014 | 4. 3

    6. April 16, 2014 | May 28, 2014. H | April 16, 2014 | 5. 2

    7. Tuesday, April 25, 2007 April 15, 2014. H | Tuesday, April 25, 2007 6. 1

    If you look at the output above, it dates back in the min_dt_from_grp column.

    MY question is if the analytical function calculates for a particular/set group, which is by statute and for what min (date_from) partition is 25-apr-2007 for the GROUP H (Status column), then why I have different values returned by the query above in the min_dt_from_grp column.

    Hello

    Because you have specified an ORDER BY clause for the analytical function. In doing so, you calculate the rows on a window. Since you have not specified a windowing clause, the default applies:

    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

  • Analytical functions: FIRST vs FIRST_VALUE

    Hello

    Can someone please help me understand the difference between PRIME and FIRST_VALUE in Anaytic functions.

    I tried below 2 queries, but I see the same output. The only difference I see is that the field of the SAL is ordered FIRST_VALUE, but not the FIRST.

    SELECT ename,

    DEPTNO,

    SAL,

    MIN (SAL) keep (dense_rank FIRST

    ORDER BY sal) by (deptno partition) FIRST

    EMP;

    SELECT ename,

    DEPTNO,

    SAL,

    FIRST_VALUE (SAL) over (partition BY deptno arrested by sal) FIRST

    EMP;

    With the help of: Windows 8.1

    Database Oracle 12 c Enterprise Edition Release 12.1.0.1.0 - 64 bit Production

    PL/SQL Release 12.1.0.1.0 - Production

    "CORE 12.1.0.1.0 Production."

    AMT for 64-bit Windows: Version 12.1.0.1.0 - Production

    NLSRTL Version 12.1.0.1.0 - Production

    Hello

    Here is an example of when you can use the FIRST analytic function.

    Say you want the average sal for each Department, but only for the first year (taken from the hiredate column) in the Department (i.e., the column called f in the query below).

    WITH got_hireyear AS

    (

    SELECT deptno and ename, sal, hiredate

    EXTRACT (YEAR FROM hiredate) AS hireyear

    FROM scott.emp

    )

    SELECT deptno, hireyear, hiredate, ename, sal

    AVG (sal) DUNGEON (DENSE_RANK FIRST ORDER BY hireyear)

    COURSES (PARTITION BY deptno

    ) In the FORM f

    FIRST_VALUE (sal) over (PARTITION BY deptno

    ORDER BY hireyear

    ) AS fv

    AVG (sal) over (PARTITION BY deptno

    hireyear

    ), A

    OF got_hireyear

    ORDER BY deptno

    hireyear

    ename

    ;

    Output:

    HIREYEAR ENAME SAL HIREDATE DEPTNO F FV HAS
    ------ ---------- ----------- ---------- ------ --------- ------ ---------
    10 1981 9 June 1981 CLARK 2450 2450 3725,00 3725.00
    10 1981 17 November 1981 KING 5000 3725,00 2450 3725.00
    10 1982 23 January 1982 MILLER 1300 3725,00 2450 1300.00

    20, 1980, 17 December 1980 SMITH 800 800.00 800.00 800
    20, 1981, 3 December 1981 FORD 3000 800.00 800 2987.50
    20, 1981, 2 April 1981 JONES 2975 800.00 800 2987.50
    20, 1987, 23 May 1987 ADAMS 1100 800.00 800 2050.00
    20, 1987, 19 April 1987 SCOTT 3000 800.00 800 2050.00

    30 1981 20 February 1981 ALLEN 1600 1566.67 950 1566.67
    May 30 1981 1st 1981 BLAKE 2850 1566.67 950 1566.67
    December 30 1981 3 1981 JAMES 950 1566.67 950 1566.67
    30 1981 28 - sep - 1981 MARTIN 1250 1566.67 950 1566.67
    30-08 - sep - 1981 1981 TURNER 1500 1566.67 950 1566.67
    30 1981 22 February 1981 WARD 1250 1566.67 950 1566.67

    The analytical FIRST_VALUE function can do (except in the very special case where only 1 row has the lowest hireyear, as in deptno = 20).  AVG analysis can do (except in the very special case that all lines have the same hireyear as in deptno = 30).

  • without analytic function

    Hello experts.

    I have data similar to what follows below

    create table t1
    (
      id number(30),
      description varchar(4000)
    
    
    );
    
    insert into t1 values (1, 'zone');
    insert into t1 values (2, 'small');
    
    
    create table t2
    (
       id number(30),
       place varchar(4000),
       info varchar(4000)
    
    );
    
    insert into t2 values (1, 'USA', 'Class U');
    insert into t2 values (1, 'Mexico', 'Class M');
    insert into t2 values (2, 'Germany', 'Class G');
    

    I need help with something similar to what follows below without using any analytic function

    Description of the ID info Place

    1 box USA class U

    Mexico 1 M class

    2 small Germany class G

    Any help is appreciated. Thank you

    Hello

    user13328581 wrote:

    ... I use an older version of oracle. Oracle 7.

    Normally, your developers are older than your software.

    You should be able to do what you want with a self-join on t2; a copy (d) should be displayed, and the other copy (c) contains all related values you need for comparison.

    SELECT t2d.id

    DECODE (t2d.place

    MAX (t2c.place)

    t1.description

    ) AS description

    t2d.place

    t2d.info

    FROM t1

    , t2 t2d - display

    t2 t2c - compare

    WHERE t1.id = t2d.id

    AND t2d.id = t2c.id

    GROUP BY t1.description

    t2d.id

    t2d.place

    t2d.info

    ORDER BY t2d.id

    t2d.place DESC

    ;

    Output:

    ID DESCRIPTION PLACE INFO

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

    1 box USA class U

    Mexico 1 M class

    2 small Germany class G

    I've tested this in Oracle 11, but it should work in Oracle 7.

    If this isn't the case, you may need to create a view.

  • Analytic Functions

    Hello

    Don't you know that it is the analytical function used to access an earlier date for example table RRODUCT

    Date amount CN code
    25/09/2012100020
    26/09/2013200015
    27/09/201110008
    28/09/2012200012
    29/09/201320002
    30/09/20041000

    4

    and this table contains more than 1000 lines in difeerent years now, I want to get the amount in a given year and the previous year like this 20 + 15 + 12 + 4

    I need analytical control that find the previous year 2012 if my year 2013 or find out if 2010 my 2011 yeaar

    You can use the YEAR-1 right? SHIFT of analytic function can be used to access the previous line. Your condition is to get the value of the previous year and previous row not. If this isn't what you are looking for then can you post output necessary for data provided?

  • analytical functions in oracle

    Hi I am new to oracle analytical functions

    I do not know how to use and where to use real-time, please send me the useful any url for it.

    I read in the Oracle Documentation , but it's not understand for me.

    Please provide me with any other useful URL, I'll read to those.if you have examples, please report it in the present.

    Thank you

    Check this box:

    ORACLE-BASE - Analytic Functions

    Analytical functions for example. Oracle FAQ

  • Drive the analytic function


    Hello

    I have a doubt about this analytical function to lead,

    I have this table,

    create table test3 (no number, name varchar2 (30));


    Insert into TEST3 (NO, NAME) values (1, 'fen');
    Insert into TEST3 (NO, NAME) Values (3, 'DEN');
    Insert into TEST3 (NO, NAME) values (2, 'Sun');
    Insert into TEST3 (NO, NAME) values (2, 'sen');
    Insert into TEST3 (NO, NAME) values (1, 'end');
    COMMIT;

    I put like that with this request.


    Select lead don't (don't) over (partition by any order of name), name of test3.

    NO NAME

    1 fen
    end
    2 Sun
    Sen
    DEN

    But I need as below output, I am unable to get the third 'NO' that has a value, I get null for that, even if I partitioned
    by the 'NO '.

    NO NAME

    1 fen
    end
    2 Sun
    Sen
    3 DEN

    Please clear my doubt.

    Thanks in advance.

    Like this

    Select decode (NWR, 1, no, null) no

    name

    de)

    Select row_number() over (partition by any order by name) rno

    None

    name

    of test3

    )

  • Analytical function?

    Hello

    I have two tables b rates and transactions (b).

    For each b.FS, I want to know new amount (b.amt time a.rate to the corresponding line of FS b and if a.na is valid based on the flag of the exclusion and the interval defined in the table's).

    It is much easier to explain with an example.

    So here we go...

    Exclude_flag = E (exclude): for b.fs = 433638, b.na = 80000. I have 2 lines in the table for this fs.  Both have E exclude_flag (exclude).  I want to go on all the lines in this FS in the table in a query and I return only one row in the result, if and only if b.na falls out of scope of a.na_min_value and a.na_max_values.  In this example, it falls outside the range excluded for both lines (first two lines of the table a).

    Similarly, exclude_flag = I (Include). for b.fs = 432828, b.na = 17200. I have 2 lines in the table for this fs.  Both have an exclude_flag of I (include).  I want to go on all the lines in this FS in the table in a query and I return only one row in the result, if and only if b.na is between a.na_min_value and a.na_max_values.  In this example, it falls in the range of both the range include for the two lines (line 6 and 7 of the table a).

    The following query gives me two lines for each b.fs.  It is possible to get what I'm looking for simply using sql (possibly write the analytical function?) or I have to write the pl/sql routine for this?

    WITH rates_table

    Did YOU (select ' E' include_exclude_flag, "81000 ' na_min_value, na_max_value '81999', '433638' FS, 0.8 of double rate

    UNION

    Select 'E' include_exclude_flag, na_min_value '84000', na_max_value '84999', '433638' FS, 0.8 of double rate

    UNION

    Select 'I' include_exclude_flag, na_min_value '12000', na_max_value '12999', '432828' FS, rate 0.25 double

    UNION

    Select 'I' include_exclude_flag, na_min_value '13000', na_max_value '13999', '432828' FS, rate 0.25 double

    UNION

    Select 'I' include_exclude_flag, na_min_value '15000', na_max_value '15000', '432828' FS, rate 0.25 double

    UNION

    Select 'I' include_exclude_flag, na_min_value '16100', na_max_value '18000', '432828' FS, rate 0.25 double

    UNION

    Select 'I' include_exclude_flag, '17100' na_min_value, na_max_value '18000', '432828' FS, rate 0.25 double

    UNION

    Select 'I' include_exclude_flag, na_min_value '02440', na_max_value '02470', '016532' FS, 0.35 rate double

    UNION

    Select 'E' include_exclude_flag, na_min_value ' 21000 ', '21000' na_max_value, ' 200020' FS, 0.35 double rate).

    transaction_table AS

    (select '433638' FS '80000' NA, 300 double amt)

    Union

    Select '432828' FS '17200' NA, amt 500 double

    )

    Select * from rates_table a, transaction_table b

    where 1 = 1

    and ((b.na PAS entre a.na_min_value et a.na_max_value et a.include_exclude_flag = «E») GOLD ())

    b.na between a.na_min_value and a.na_max_value and a.include_exclude_flag = 'I'))

    and b.fs = a.fs

    ;

    Any help is greatly appreciated.  I use oracle 11i

    @OP,

    For this kind of problems, we get the number of rows that satisfy the required conditions or who do not meet the required conditions. And then eliminate the line that should be eliminated.

    As below, I calculate four counts (number of join lines)

    EOBCNT - excluded and Out of Bound

    EIBCNT - excluded and in the limit

    IOBCNT - included and Out of Bound

    IIBCNT - included and within the limits

    Once those are calculated, simply return the lines that have EIBCNT and IOBCNT are zero.

    For Ex:

    > WITH

    rates_table

    AS LONG AS)

    Select 'E' include_exclude_flag, na_min_value '79999', na_max_value '79999', '433638' FS, 0.8 double UNION rates

    -Select 'E' include_exclude_flag, na_min_value ' 79999', na_max_value '80000', '433638' FS, 0.8 double UNION rate - TEST - THE

    -If you uncomment the last line and then 433638 will not be returned

    Select 'E' include_exclude_flag, "81000 ' na_min_value, na_max_value '81999', '433638' FS, 0.8 double UNION rates

    Select 'E' include_exclude_flag, na_min_value '84000', na_max_value '84999', '433638' FS, 0.8 double UNION rates

    Select 'I' include_exclude_flag, na_min_value '12000', na_max_value '12999', '432828' FS, 0.25 rate double UNION

    Select 'I' include_exclude_flag, na_min_value '13000', na_max_value '13999', '432828' FS, 0.25 rate double UNION

    Select 'I' include_exclude_flag, na_min_value '15000', na_max_value '15000', '432828' FS, 0.25 rate double UNION

    Select 'I' include_exclude_flag, na_min_value '16100', na_max_value '18000', '432828' FS, 0.25 rate double UNION

    Select 'I' include_exclude_flag, '17100' na_min_value, na_max_value '18000', '432828' FS, 0.25 rate double UNION

    Select 'I' include_exclude_flag, na_min_value '02440', na_max_value '02470', '016532' FS, 0.35 rate double UNION

    Select 'E' include_exclude_flag, na_min_value ' 21000 ', '21000' na_max_value, ' 200020' FS, 0.35 double rate).

    transaction_table AS

    (select '433638' FS '80000' NA, amt 300 Union double

    Select '432828' FS '17200' NA, amt 500 double

    )

    getcnts as)

    SELECT a.*

    b.na, b.amt

    , sum (case when (b.na NOT BETWEEN a.na_min_value)

    AND a.na_max_value

    AND a.include_exclude_flag = 'E '.

    end) then 1 else 0) on (a.fs partition) Eobcnt

    , sum (case when (b.na NOT BETWEEN a.na_min_value)

    AND a.na_max_value

    AND a.include_exclude_flag = 'I '.

    end) then 1 else 0) on (a.fs partition) Iobcnt

    , sum (case when (b.na BETWEEN a.na_min_value)

    AND a.na_max_value

    AND a.include_exclude_flag = 'E '.

    end) then 1 else 0) on (a.fs partition) Eibcnt

    , sum (case when (b.na BETWEEN a.na_min_value)

    AND a.na_max_value

    AND a.include_exclude_flag = 'I '.

    end) then 1 else 0) on (a.fs partition) Iibcnt

    OF rates_table one

    transaction_table b

    WHERE b.fs = a.fs

    )

    getrows as)

    Select x.*, row_number() on

    (partition by order of fs with null desc) getcnts rn x

    where IOBCNT = 0 and eibcnt = 0 - remove lines that are not needed (IF and ONLY if)

    )

    Select * from getrows

    where rn = 1 - to limit a SINGLE row (arbitrarily)

    INCLUDE_EXCLUDE_FLAG NA_MIN_VALUE NA_MAX_VALUE FS RATE NA AMT EOBCNT IOBCNT EIBCNT IIBCNT RN

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

    433638 84999 84000.8 E 80000 300 3 0 0 0 1

    I hope this helps.

  • Order of evaluation of analytic function

    Hello

    have question quite like this:

    with

    -This query selects a 'representative' acct_id by Group (about 300 lines in total)

    acct_repres as

    (

    Select distinct acct_id, origin_id, acct_parm_id of

    (

    Select a.*

    source_id

    , dense_rank() over (partition by order source_id by nulls first, acct_id acct_nbr origin_id) as odr

    account a join account_parm on (a.parm_id = ap.acct_parm_id) ap

    )

    where odr = 1

    )

    Select col1

    col2

    , (select accct_id from ar acct_repres where ar.acct_parm_id = t2.acct_parm_id) col3

    , col4 (select count (1) of acct_repres)

    of une_table t1

    Join other_table t2 on (...)

    And here it is. "Acct_repres" subquery returns more than 300 lines when it is run separately. But when it is used in CTE sometimes (depending on the execution plan) she seems to have that one line - the value in the column col4 is '1 ',.

    While the value of col3 is NULL for most of the cases.

    It looks like the the dense_rank function and the State 'where odr = 1' are evaluated at the end.

    When I use the hint to MATERIALIZE the result was the same.

    But when I put the result of account_repres in the dedicated table and use this table instead of CTE output is correct.

    What is a bug? Or I do something wrong?

    PS: my version of db is 11 GR 1 material (11.1.0.7).

    some unorganized comments:

    -analytical functions are evaluated towards the end of the execution ("' the last set of operations performed in a query with the exception of the final ORDER BY clause"- http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions004.htm")

    -but still the result of a SQL query must be deterministic, so I think that your results are not an expected behavior

    -the CBO has some problems with common table expressions (http://jonathanlewis.wordpress.com/2012/05/24/subquery-factoring-7/) if they are of great assistance in the structuring of complex queries. In these cases, you can avoid problems by using inline views

    -Your query uses the common table expressions in scalar subqueries and scalar subqueries are also likely to confuse the CBO. In addition, they are executed once for each row in your result set (or at least for each different correlation value) and can have a negative impact on the performance of the queries in many cases. Often, they can be replaced by outer joins.

    -you say that the suspicion of materialization brings you an erroneous result: the indicator object (online) gives you the correct results?

    Concerning

    Martin Preiss

  • Return one row of an analytic function

    Hello

    I pulled the following query:

    Select ID_STORNO, first_value (COD_CONTATTO) ON (Partition of COD_CONTATTO

    order of COD_PRIORITY asc, desc FT_DAT_OPEN_CNT

    rows between unbounded preceding and following unbounded)

    as COD_CONTATTO_LAST

    of WT_STR_ESG_CONTATTO;

    The result is:

    2160603C1-H83J1N
    2160603C8-9FOHXJS
    2258072C1-H83J1N

    But I just need to take the following lines

    2160603C8-9FOHXJS
    2258072C1-H83J1N

    Because for the same value of ID_STORNO, I just need to get a value of COD_CONTATTO (to select the best value using COD_PRIORITY and FT_DAT_OPEN_CNT). What is wrong inside the query? I just use 2 or 3 times the oracle analytic functions.

    Best regards

    As SomeoneElse... you need a where clause clause in order to choose the ones you want.

    To do this, the typical is to select a column that you use for this reason, such as:

    "I want to just the first record in each group..."

    Select id_storno, cod_contatto_last from)

    Select ID_STORNO, first_value (COD_CONTATTO) ON (Partition of COD_CONTATTO

    order of COD_PRIORITY asc, desc FT_DAT_OPEN_CNT

    rows between unbounded preceding and following unbounded)

    as COD_CONTATTO_LAST,

    ROW_NUMBER() OVER (Partition of COD_CONTATTO

    order of COD_PRIORITY asc, desc FT_DAT_OPEN_CNT

    rows between unbounded preceding and following unbounded)

    as rnum

    of WT_STR_ESG_CONTATTO

    )

    where rnum = 1

    /

    I prefer to use rownumber in this case, so I always have a rnum = 1...

    Usually, you must use the same partition/command by as your other folders (it is usually a good idea... maybe not, depending on your needs, however)

  • SQL using the analytic function


    Hi all

    I want a help in the creation of my SQL query to retrieve the data described below:

    I have a test of sample table containing data as below:

    State ID Desc

    MICHAEL 1 T1

    ACTIVE 2 T2

    T3 3 SUCCESS

    DISABLE THE T4 4

    The thing I want to do is to select all the lines with an ACTIVE status in the table but is there is no ACTIVE status, my request will give me the last line with MICHAEL status.

    I can do this in a single request by using the analytical function for example, if yes can yiu help me on the request of unpacking.

    Kind regards

    Raluce

    Something like that?

    I had to fix it.

    with testdata until)
    Select 1 id, "T1" dsc "DISABLED" status of Union double all the
    Select 2 id, 'T2' dsc, the status "ACTIVE" of all the double union
    Select id 3, "T3" dsc, the status of 'SUCCESS' of all the double union
    Select 4 id, "T4" dsc "DISABLED" status of double
    )

    Select
    ID
    dsc
    status
    of testdata
    where
    status =
    -case when (select count (*) in testdata where status = 'ACTIVE') > 0
    then 'ACTIVE '.
    Another 'DISABLED '.
    end
    and)
    ID in (select id from testdata where status = ' ACTIVE')
    or
    ID = (select max (id) in testdata when status = 'DISABLED')
    )

    STATE ID DSC

    '2' 'T2' 'ACTIVE '.

    Maybe it's more efficient

    Select
    ID
    dsc
    status
    of testdata
    where
    status =
    -case when (select count (*) in testdata where status = 'ACTIVE') > 0
    then 'ACTIVE '.
    Another 'DISABLED '.
    end
    and
    ID =)
    -case when (select count (*) in testdata where status = 'ACTIVE') > 0
    then id
    on the other
    (select max (id) in testdata when status = 'DISABLED')
    end
    )

    Post edited by: correction of chris227

    Post edited by: chris227
    extended

Maybe you are looking for