Analytical function count(*) with order by Rows unbounded preceding

Hi
I have query about analytical function count(*) with order by (col) ROWS unbounded preceding.
If i removed order by rows unbouned preceding then it behaves some other way.
Can anybody tell me what is the impact of order by ROWS unbounded preceding with count(*) analytical function?
Please help me and thanks in advance.

Sweety,
CURRENT ROW is the default behaviour of the analytical function if no windowing clause is provided. So if you are giving ROWS UNBOUNDED PRECEDING, It basically means that you want to compute COUNT(*) from the beginning of the window to the current ROW. In other words, the use of ROWS UNBOUNDED PRECEDING is to implicitly indicate the end of the window is the current row
The beginning of the window of a result set will depend on how you have defined your partition by clause in the analytical function.
If you specify ROWS 2 preceding, then it will calculate COUNT(*) from 2 ROWS prior to the current row. It is a physical offset.
Regards,
Message was edited by:
henryswift

Similar Messages

  • Using analytical function - value with highest count

    Hi
    i have this table below
    CREATE TABLE table1
    ( cust_name VARCHAR2 (10)
    , txn_id NUMBER
    , txn_date DATE
    , country VARCHAR2 (10)
    , flag number
    , CONSTRAINT key1 UNIQUE (cust_name, txn_id)
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9870,TO_DATE ('15-Jan-2011', 'DD-Mon-YYYY'), 'Iran', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9871,TO_DATE ('16-Jan-2011', 'DD-Mon-YYYY'), 'China', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9872,TO_DATE ('17-Jan-2011', 'DD-Mon-YYYY'), 'China', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9873,TO_DATE ('18-Jan-2011', 'DD-Mon-YYYY'), 'Japan', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9874,TO_DATE ('19-Jan-2011', 'DD-Mon-YYYY'), 'Japan', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9875,TO_DATE ('20-Jan-2011', 'DD-Mon-YYYY'), 'Russia', 1);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9877,TO_DATE ('22-Jan-2011', 'DD-Mon-YYYY'), 'China', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9878,TO_DATE ('26-Jan-2011', 'DD-Mon-YYYY'), 'Korea', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9811,TO_DATE ('17-Jan-2011', 'DD-Mon-YYYY'), 'China', 0);
    INSERT INTO table1 (cust_name, txn_id, txn_date,country,flag) VALUES ('Peter', 9854,TO_DATE ('13-Jan-2011', 'DD-Mon-YYYY'), 'Taiwan', 0);
    The requirement is to create an additional column in the resultset with country name where the customer has done the maximum number of transactions
    (with transaction flag 1). In case we have two or more countries tied with the same count, then we need to select the country (among the tied ones)
    where the customer has done the last transaction (with transaction flag 1)
    e.g. The count is 2 for both 'China' and 'Japan' for transaction flag 1 ,and the latest transaction is for 'Japan'. So the new column should contain 'Japan'
    CUST_NAME TXN_ID TXN_DATE COUNTRY FLAG country_1
    Peter 9811 17-JAN-11 China 0 Japan
    Peter 9854 13-JAN-11 Taiwan 0 Japan
    Peter 9870 15-JAN-11 Iran 1 Japan
    Peter 9871 16-JAN-11 China 1 Japan
    Peter 9872 17-JAN-11 China 1 Japan
    Peter 9873 18-JAN-11 Japan 1 Japan
    Peter 9874 19-JAN-11 Japan 1 Japan
    Peter 9875 20-JAN-11 Russia 1 Japan
    Peter 9877 22-JAN-11 China 0 Japan
    Peter 9878 26-JAN-11 Korea 0 Japan
    Please let me know how to accomplish this using analytical functions
    Thanks
    -Learnsequel

    Does this work (not spent much time checking it)?
    WITH ana AS (
    SELECT cust_name, txn_id, txn_date, country, flag,
            Sum (flag)
                OVER (PARTITION BY cust_name, country)      n_trx,
            Max (CASE WHEN flag = 1 THEN txn_date END)
                OVER (PARTITION BY cust_name, country)      l_trx
      FROM cnt_trx
    SELECT cust_name, txn_id, txn_date, country, flag,
            First_Value (country) OVER (PARTITION BY cust_name ORDER BY n_trx DESC, l_trx DESC) top_cnt
      FROM ana
    CUST_NAME      TXN_ID TXN_DATE  COUNTRY          FLAG TOP_CNT
    Fred             9875 20-JAN-11 Russia              1 Russia
    Fred             9874 19-JAN-11 Japan               1 Russia
    Peter            9873 18-JAN-11 Japan               1 Japan
    Peter            9874 19-JAN-11 Japan               1 Japan
    Peter            9872 17-JAN-11 China               1 Japan
    Peter            9871 16-JAN-11 China               1 Japan
    Peter            9811 17-JAN-11 China               0 Japan
    Peter            9877 22-JAN-11 China               0 Japan
    Peter            9875 20-JAN-11 Russia              1 Japan
    Peter            9870 15-JAN-11 Iran                1 Japan
    Peter            9878 26-JAN-11 Korea               0 Japan
    Peter            9854 13-JAN-11 Taiwan              0 Japan
    12 rows selected.

  • Analytical Function - COUNT issue

    Hello All,
    DB Oracle 11g running on Linux x86 64-bit platform ..
    I'm curious to know why the below two sets of queries produce different reults.
    Q 1
    WITH TEMP AS
    SELECT 'ONE' VAL, 5 PAR FROM DUAL UNION ALL
    SELECT 'ONE' VAL, 7 PAR FROM DUAL UNION ALL
    SELECT 'FIVE' VAL, 17 PAR FROM DUAL UNION ALL
    SELECT 'FOUR' VAL, 0 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, 78 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, 34 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, -4 PAR FROM DUAL UNION ALL
    SELECT 'TWO' VAL, 6 PAR FROM DUAL UNION ALL
    SELECT 'TWO' VAL, 12 PAR FROM DUAL 
    SELECT DISTINCT SUM(PAR) OVER(PARTITION BY VAL), VAL CNT FROM TEMP;
    Q2
    WITH TEMP AS
    SELECT 'ONE' VAL, 5 PAR FROM DUAL UNION ALL
    SELECT 'ONE' VAL, 7 PAR FROM DUAL UNION ALL
    SELECT 'FIVE' VAL, 17 PAR FROM DUAL UNION ALL
    SELECT 'FOUR' VAL, 0 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, 78 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, 34 PAR FROM DUAL UNION ALL
    SELECT 'THREE' VAL, -4 PAR FROM DUAL UNION ALL
    SELECT 'TWO' VAL, 6 PAR FROM DUAL UNION ALL
    SELECT 'TWO' VAL, 12 PAR FROM DUAL 
    SELECT DISTINCT SUM(PAR) OVER(PARTITION BY VAL ORDER BY PAR) CNT, VAL FROM TEMP;
    The only difference between the 2 queries is Q2 has the 'ORDER BY' extra.
    For Q2, I was assuming the partitions are ordered by PAR and the SUM is applied over the partition. Obviously, the results prove my assumption is wrong.
    So, Q2 is just as good as select * from temp;

    Hi,
    You're right about "ORDER BY par"; it means that the SUM will be from the lowest value of par up to and including the current row.
    I think you're ignoring "PARTITION BY val", which means every distinct value of val will be a world unto itself, not affected by any rows with a different value of val.  Since val is different on every row, that means the SUM shown will always be the SUM of just that 1 item, so SUM (par) will indeed be the same as par.
    Try it without the PARTITION BY clause.

  • Problem with Analytical function

    hi,
    I have two tables and my expected result is given below..
    I used the LEAD function to get (start_Date and new_Date) which i have shown in my expected result..my problem is with rel_type and org_id. I am not able to get those values to its corresponding dates..please can any one help...
    Table A
    ID     START_DATE     END_DATE     REL_TYPE
    5001     5/12/2005     7/1/2005     PARTIAL
    5001     7/1/2005     7/4/2005     NOTHING
    5001     7/4/2005     1/1/5000     FULL
    Table B
    ID     ORG_ID     START_DATE     END_DATE
    5001     102     3/1/2002     3/10/2004
    5001     103     3/10/2004     8/1/2005
    5001     102     8/1/2005     1/1/5000
    Expected Result
    start_Date new_date rel_type org_id
    3/1/2002     3/10/2004 partial 102
    3/10/2004 5/12/2005 partial 103
    5/12/2005 7/1/2005 partial 103
    7/1/2005     7/4/2005 Nothing 103
    7/4/2005     8/1/2005 FULL 103
    8/1/2005     1/1/5000 FULL 102
    rds,
    Naga

    Is this correct?
    <s></s>
    with A as
    ( select 5001 id ,to_date('5/12/2005') start_date, to_date('7/1/2005') end_date,'PERTIAL' rel_type from dual
      union all
      select 5001,to_date('7/1/2005'),to_date('7/4/2005'), 'NOTHING' from dual
      union all
      select 5001,to_date('7/4/2005'),to_date('1/1/5000'), 'FULL' from dual
    ,B as
    ( select 5001 id ,102 org_id, to_date('3/1/2005') start_date, to_date('3/10/2005') end_date from dual
      union all
      select 5001, 103, to_date('3/10/2005'),to_date('8/1/2005') from dual
      union all
      select 5001, 102, to_date('8/1/2005'),to_date('1/1/5000') from dual
    /* Data end */
    select
      start_date
      ,case when rel_type is null then lead(start_date) over (order by start_date)
            else new_date end NEW_DATE
      ,last_value(rel_type ignore nulls)
         over (order by start_date desc rows unbounded preceding) REL_TYPE
      ,org_id
    from (
      select
         case when B.start_date < A.start_date then A.start_date else B.start_date end START_DATE
        ,case when B.end_date   > A.end_date   then A.end_date   else B.end_date   end NEW_DATE
        ,A.rel_type
        ,B.org_id
      from A,B
      where A.start_date <= B.end_date and B.start_date <= a.end_date
      union all
      select B.start_date, B.end_date, null, B.org_id
      from B
      where start_date <= all (select start_date from A)
    order by start_date,org_id
    START_DATE NEW_DATE   REL_TYP     ORG_ID
    03/01/2005 03/10/2005 PERTIAL        102
    03/10/2005 05/12/2005 PERTIAL        103
    05/12/2005 07/01/2005 PERTIAL        103
    07/01/2005 07/04/2005 NOTHING        103
    07/04/2005 08/01/2005 FULL           103
    08/01/2005 01/01/5000 FULL           102
    6 rows selected.
    Oops, there were mistakes on START_DATE NEW_DATE
    It has been corrected.
    Message was edited by:
            ushitaki

  • Tuning sql with analytic function

    Dear friends I've developed one sql :
    with REP as
    (select /*+ MATERIALIZE */ branch_code,
       row_number() over(partition by branch_code, account order by bkg_date desc  ) R,
             account,
             bkg_date,
             lcy_closing_bal
        from history t
    select REP1.branch_code,
           REP1.account,
           REP1.bkg_date,
           REP1.lcy_closing_bal,
             NULL  AS second,
           REP2.bkg_date        bkg_date2,
           REP2.lcy_closing_bal lcy_closing_bal2,
            NULL  AS third,
           REP3.bkg_date        bkg_date3,
           REP3.lcy_closing_bal lcy_closing_bal3
      from (SELECT * FROM REP WHERE R=1) REP1, (SELECT * FROM REP WHERE R=2) REP2, (SELECT * FROM REP WHERE R=3) REP3
    where
           (REP1.BRANCH_CODE = REP2.BRANCH_CODE(+) AND REP1.ACCOUNT = REP2.ACCOUNT(+)) AND
           (REP1.BRANCH_CODE = REP3.BRANCH_CODE(+) AND REP1.ACCOUNT = REP3.ACCOUNT(+))The point is I want to restrict (tune) REP before it used ,because , as you can see I need maximum three value from REP (where R=1,R=2,R=3) . Which analytic function and with wich options I have to use to receive only 3 values in each branch_code,account groups at the materializing time ?

    Radrigez wrote:
    Dear friends I've developed one sql :
    with REP as
    from (SELECT * FROM REP WHERE R=1) REP1,
    (SELECT * FROM REP WHERE R=2) REP2,
    (SELECT * FROM REP WHERE R=3) REP3
    where
    (REP1.BRANCH_CODE = REP2.BRANCH_CODE(+) AND REP1.ACCOUNT = REP2.ACCOUNT(+)) AND
    (REP1.BRANCH_CODE = REP3.BRANCH_CODE(+) AND REP1.ACCOUNT = REP3.ACCOUNT(+))
    The first step is to put your subquery (which doesn't need to be materialized) into an inline view and restrict the result set on r in (1,2,3) as suggested by thtsang - you don't need to query the same result set three times.
    Then you're looking at a simple pivot operation (assuming the number of rows you want per branch and account is fixed). If you're on 11g search the manuals for PIVOT, on earlier versions you can do this with a decode() or case() operator.
    Step 1 (which could go into another factored subquery) would be something like:
    select
            branch_code, account,
            case r = 1 then bkg_date end bkg_date,
            case r = 1 then lcy_closing_bal end lcy_closing_bal,
            case r = 2 then bkg_date end bkg_date2,
            case r = 2 then lcy_closing_bal end lcy_closing_bal2,
            case r = 3 then bkg_date end bkg_date3,
            case r = 3 then lcy_closing_bal end lcy_closing_bal3
    from
            repThis gives you the eight necessary columns, but still (up to) three rows per branch/account.
    Then you aggregate this (call it rep1) on branch and account.
    select
            branch_code, account,
            max(bkg_date),
            max(lcy_closing_bal),
            max(bkg_date2),
            max(lcy_closing_bal2),
            max(bkg_date3),
            max(lcy_closing_bal3)
    from
            rep1
    group by
            branch_code, account
    order by
            branch_code, accountRegards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    Author: <b><em>Oracle Core</em></b>

  • Return multiple columns from an analytic function with a window

    Hello,
    Is it possible to obtain multiple columns from an analytic function with a window?
    I have a table with 4 columns, an id, a test id, a date, and the result of a test. I'm using an analytic function to obtain, for each row, the current test value, and the maximum test value in the next 2 days like so:
    select
    id,
    test_id,
    date,
    result,
    MAX ( result ) over ( partition BY id, test_id order by date RANGE BETWEEN CURRENT ROW AND INTERVAL '2' DAY FOLLOWING ) AS max_result_next_two_day
    from table
    This is working fine, but I would like to also obtain the date when the max result occurs. I can see that this would be possible using a self join, but I'd like to know if there is a better way? I cannot use the FIRST_VALUE aggregate function and order by result, because the window function needs to be ordered by the date.
    It would be a great help if you could provide any pointers/suggestions.
    Thanks,
    Dan
    http://danieljamesscott.org

    Assuming RESULT is a positive integer that has a maximum width of, say 10,
    and assuming date has no time-component:
    select
       id
      ,test_id
      ,date
      ,result
      ,to_number(substr(max_result_with_date,1,10)) as max_result_next_two_day
      ,to_date(substr(max_result_with_date,11),'YYYYMMDD') as date_where_max_result_occurs
    from (select
            id
           ,test_id
           ,date
           ,result
           ,MAX(lpad(to_char(result),10,'0')||to_char(date,'YYYYMMDD'))
               over (partition BY id, test_id
                     order by date
                     RANGE BETWEEN CURRENT ROW AND INTERVAL '2' DAY FOLLOWING )
            AS max_result_with_date
          from table)

  • Completion of data series by analytical function

    I have the pleasure of learning the benefits of analytical functions and hope to get some help
    The case is as follows:
    Different projects gets funds from different sources over several years, but not from each source every year.
    I want to produce the cumulative sum of funds for each source for each year for each project, but so far I have not been able to do so for years without fund for a particular source.
    I have used this syntax:
    SUM(fund) OVER(PARTITION BY project, source ORDER BY year ROWS UNBOUNDED PRECEDING)
    I have also experimented with different variations of the window clause, but without any luck.
    This is the last step in a big job I have been working on for several weeks, so I would be very thankful for any help.

    If you want to use Analytic functions and if you are on 10.1.3.3 version of BI EE then try using Evaluate, Evaluate_aggr that support native database functions. I have blogged about it here http://oraclebizint.wordpress.com/2007/09/10/oracle-bi-ee-10133-support-for-native-database-functions-and-aggregates/. But in your case all you might want to do is have a column with the following function.
    SUM(Measure BY Col1, Col2...)
    I have also blogged about it here http://oraclebizint.wordpress.com/2007/10/02/oracle-bi-ee-101332-varying-aggregation-based-on-levels-analytic-functions-equivalence/.
    Thanks,
    Venkat
    http://oraclebizint.wordpress.com

  • Analytic function problem

    Hi,
    I have a problem using analytic function: when I execute this query
    SELECT TSIUPSITE, TSIUPCEAN , TSIUPDATE, sum(TSIUPCA) TSIUPCA, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
    sum(TSIUPQTE) TSIUPQTE,sum(TSIUPQTEP) TSIUPQTEP, TSIUPMDIU,TSIUPMDar,
    sum(TSIUPCRIU) TSIUPCRIU,sum(TSIUPCRAR) TSIUPCRAR, trunc(TSIUPDCRE) TSIUPDCRE ,trunc(TSIUPDMAJ) TSIUPDMAJ ,
    TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
    TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, sum(TSIUPMHT) TSIUPMHT, 0 vtanfisc,
    TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV ,count(*) over (partition by TSIUPSITE,TSIUPCEAN,TSIUP_TRT ) CONTA_ARTICOLO
    FROM TST_FLIISR_VTEREMART
    WHERE 1=1 --TSIUP_TRT = 1
    AND TSIUPDATE=to_date('27082012','ddmmyyyy')
    and TSIUP_NTRX =172
    AND TSIUPSITE = 10025
    AND TSIUPCEAN = '8012452018825'
    GROUP BY TSIUPSITE, TSIUPCEAN , TSIUPDATE, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
    TSIUPMDIU,TSIUPMDar, trunc(TSIUPDCRE),trunc(TSIUPDMAJ),TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
    TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, 0,
    TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV
    ORDER BY TSIUPSITE,TSIUPDATE ;
    I have the error ORA-00979: not a GROUP BY expression related to TSIUP_TRT field,infact, if I execute this one
    SELECT TSIUPSITE, TSIUPCEAN , TSIUPDATE, sum(TSIUPCA) TSIUPCA, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
    sum(TSIUPQTE) TSIUPQTE,sum(TSIUPQTEP) TSIUPQTEP, TSIUPMDIU,TSIUPMDar,
    sum(TSIUPCRIU) TSIUPCRIU,sum(TSIUPCRAR) TSIUPCRAR, trunc(TSIUPDCRE) TSIUPDCRE ,trunc(TSIUPDMAJ) TSIUPDMAJ ,
    TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
    TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, sum(TSIUPMHT) TSIUPMHT, 0 vtanfisc,
    TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV ,count(*) over (partition by TSIUPSITE,TSIUPCEAN ) CONTA_ARTICOLO
    FROM TST_FLIISR_VTEREMART
    WHERE 1=1 --TSIUP_TRT = 1
    AND TSIUPDATE=to_date('27082012','ddmmyyyy')
    and TSIUP_NTRX =172
    AND TSIUPSITE = 10025
    AND TSIUPCEAN = '8012452018825'
    GROUP BY TSIUPSITE, TSIUPCEAN , TSIUPDATE, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
    TSIUPMDIU,TSIUPMDar, trunc(TSIUPDCRE),trunc(TSIUPDMAJ),TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
    TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, 0,
    TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV
    ORDER BY TSIUPSITE,TSIUPDATE ;
    I have no problem. Now the difference between TSIUPCEAN ( or TSIUPSITE) and TSIUP_TRT is that TSIUP_TRT is not in Group By clause, but, to be honest, I don't know why I have this problem using using an analitic function.
    Thanks for help

    Hi,
    I think you are not using analytic function properly.
    Analytical functions will execute for each row. Where as Group BY will execute for groups of data.
    See below example for you reference.
    Example 1:
    -- Below query displays number of employees for each department. Since we have used analytical function for each row you are getting the number of employees based on the department id.
    SQL> SELECT e.department_id,count(*) OVER (PARTITION BY e.department_id) cnt_analytic
      2  FROM employees e
      3  WHERE e.department_id IN (10,20,30);
    DEPARTMENT_ID CNT_ANALYTIC
               10            1
               20            2
               20            2
               30            6
               30            6
               30            6
               30            6
               30            6
               30            6
    9 rows selected.
    Example 2:
    -- Since I have used GROUP BY clause I'm getting only single row for each department.
    SQL> SELECT e.department_id, count(*) cnt_group
      2  FROM employees e
      3  WHERE e.department_id IN (10,20,30)
      4  GROUP BY e.department_id;
    DEPARTMENT_ID  CNT_GROUP
               10          1
               20          2
               30          6Finally, what I'm trying to explain you is - If you use Analytical function with GROUP BY clause, the query will not give the menaing ful result set.
    See below
    SQL> SELECT e.department_id,count(*) OVER (PARTITION BY e.department_id) cnt_analytic, count(*) cnt_grp
      2  FROM employees e
      3  WHERE e.department_id IN (10,20,30)
      4  GROUP BY e.department_id;
    DEPARTMENT_ID CNT_ANALYTIC    CNT_GRP
               10            1          1
               20            1          2
               30            1          6

  • Analytical Function in Oracle

    I have a situation where i have partitioned a record set. If in any of the partition on that recordset, the value of one field(field name- status) is '45' i need to order the result of that partition by- 'outdate' desc, 'receiveddate' desc and order the other partition by 'key' desc,' sequence' desc, 'outdate' desc.
    So the query looks like -
    select row_number() over (partition by key order by sequence) RowNo, key, seq, status, outdate, receivedate from table1 where .........
    order by ????
    RowNo Key Seq status outdate receiveddate
    1 200 0 24 9/13/2009 9/12/2009
    2 200 1 23 9/10/2009 9/09/2009
    3 200 2 24 9/09/2009 9/08/2009
    1 210 0 24 9/13/2009 9/12/2009
    2 210 1 * 45 * 9/09/2009 9/08/2009
    3 210 2 24 9/10/2009 9/09/2009
    So i need to get the query that will order the first set of partition by 'key' desc,' sequence' desc, 'outdate' desc and the Second set of partition (since the status of '45' exist in second partition) by 'outdate' desc, 'receiveddate' desc .
    The output of the query should look like
    RowNo Key Seq status outdate receiveddate
    1 200 0 24 9/13/2009 9/12/2009
    2 200 1 23 9/10/2009 9/09/2009
    3 200 2 24 9/09/2009 9/08/2009
    1 210 0 24 9/13/2009 9/12/2009
    2 210 2 24 9/10/2009 9/09/2009
    3 210 1 *45 * 9/09/2009 9/08/2009
    I am not sure if this is possible using Analytical function.
    I would really appreciate if any one can light me on this.
    Thanks in advance

    Hi,
    Welcome to the forum!
    You can use analytic functions in the ORDER BY clause.
    I don't have your tables, so I'll use scott.emp to illustrate.
    The following query sorts by deptno first. After that, the sort order for departments that contain at least one Salesman is:
    (a) job
    (b) ename
    Deptno=30 happens to be the only department with a Salesman, so it is the only one sorted as above.
    The other departements will be sorted by
    (a) sal
    (b) job
    SELECT       deptno
    ,       ename
    ,       job
    ,       sal
    FROM       scott.emp
    ORDER BY  deptno
    ,            CASE
              WHEN  COUNT ( CASE
                                   WHEN  job = 'SALESMAN'
                          THEN  1
                         END
                       ) OVER (PARTITION BY deptno) > 0
              THEN  ROW_NUMBER () OVER ( PARTITION BY  deptno
                                          ORDER BY        job
                                ,            ename
              ELSE  ROW_NUMBER () OVER ( PARTITION BY  deptno
                                          ORDER BY        sal
                                ,            job
           END
    ;Output:
    .   DEPTNO ENAME      JOB              SAL
            10 MILLER     CLERK           1300
            10 CLARK      MANAGER         2450
            10 KING       PRESIDENT       5000
            20 SMITH      CLERK            800
            20 ADAMS      CLERK           1100
            20 JONES      MANAGER         2975
            20 SCOTT      ANALYST         3000
            20 FORD       ANALYST         3000
            30 JAMES      CLERK            950
            30 BLAKE      MANAGER         2850
            30 ALLEN      SALESMAN        1600
            30 MARTIN     SALESMAN        1250
            30 TURNER     SALESMAN        1500
            30 WARD       SALESMAN        1250 
    In the small set of sample data you posted, the results you want can be obtained simply using
    ORDER BY  key
    ,         outdate     DESCI assume that's just a coincidence.
    If you need help, post some sample data that really requires looking at the status column to get the right results. Post the data in some executable form, such as CREATE TABLE and INSERT statements, olr, as Salim did, a WITH clause. (Perhaps you can just add or change a couple of rows in the sample data Salim already posted.)

  • Yet another question on analytical functions

    Hi,
    A "simple" issue with date overlapping: I need to display a "y" or "n" where a start time/end time overlaps with another row for the same employee.
    For this, I used analytical functions to find out which rows were overlapping. This is what I did:
    create table test (id number, emp_id number, date_worked date, start_time date, end_time date);
    insert into test values (1, 333, to_date('2008-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 08:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS'));
    insert into test values (2, 333, to_date('2008-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 10:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 12:00:00', 'YYYY-MM-DD HH24:MI:SS'));
    insert into test values (3, 444, to_date('2008-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 08:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 09:00:00', 'YYYY-MM-DD HH24:MI:SS'));
    insert into test values (4, 333, to_date('2008-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 11:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 13:00:00', 'YYYY-MM-DD HH24:MI:SS'));
    SQL> select * from test;
            ID     EMP_ID DATE_WORKED         START_TIME          END_TIME
             1        333 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00 
             2        333 01-01-2008 00:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00  --> conflict
             3        444 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 09:00:00
             4        333 01-01-2008 00:00:00 01-01-2008 11:00:00 01-01-2008 13:00:00  --> conflict Here I see that Employee 333 is scheduled from 10 to 12 am, but it's also scheduled from 11 to 13. This is a conflict.
    To find this conflict, I did this (please correct me if this is incorrect):
    SQL> select id, emp_id, date_worked, start_time, end_time, next_date
      2  from (
      3        select lead( start_time, 1 ) over ( partition by emp_id order by start_time ) next_date,
      4               start_time, end_time, emp_id, date_worked, id
      5        from   test
      6       )
      7  where  next_date < end_time;
            ID     EMP_ID DATE_WORKED         START_TIME          END_TIME            NEXT_DATE
             2        333 01-01-2008 00:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00 01-01-2008 11:00:00So far, so good. Where I'm stuck is, I need to display the conflicts in this way:
            ID     EMP_ID DATE_WORKED         START_TIME          END_TIME            OVERLAPPED
             1        333 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00
             2        333 01-01-2008 00:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00 yes
             3        444 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 09:00:00
             4        333 01-01-2008 00:00:00 01-01-2008 11:00:00 01-01-2008 13:00:00 yes Is there a way I can achieve this?
    I tried doing a nested query with a count(*) but no success...

    I found an issue. Say we insert this row.
    insert into test values (5, 333, to_date('2008-01-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 07:00:00', 'YYYY-MM-DD HH24:MI:SS'),to_date('2008-01-01 08:00:00', 'YYYY-MM-DD HH24:MI:SS'));
    SQL> select * from test order by start_time;
            ID     EMP_ID DATE_WORKED         START_TIME          END_TIME
             5        333 01-01-2008 00:00:00 01-01-2008 07:00:00 01-01-2008 08:00:00
             1        333 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00
             3        444 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 09:00:00
             2        333 01-01-2008 00:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00 --> conflict
             4        333 01-01-2008 00:00:00 01-01-2008 11:00:00 01-01-2008 13:00:00 --> conflictIf I run the SQL suggested by Nicloei, I get:
    SQL> select id,
      2         emp_id,
      3         date_worked,
      4         start_time,
      5         end_time,
      6           Case When end_time > prev_date Or next_date > End_time Then 'Yes' Else 'No' End over_lap
      7      from (
      8            select lead( start_time, 1 ) over ( partition by emp_id order by start_time ) next_date,
      9                   lag( start_time, 1 ) over ( partition by emp_id order by start_time ) prev_date,
    10                   start_time, end_time, emp_id, date_worked, id
    11            from   test
    12           );
            ID     EMP_ID DATE_WORKED         START_TIME          END_TIME            OVER_LAP
             5        333 01-01-2008 00:00:00 01-01-2008 07:00:00 01-01-2008 08:00:00 No
             1        333 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00 Yes
             2        333 01-01-2008 00:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00 Yes
             4        333 01-01-2008 00:00:00 01-01-2008 11:00:00 01-01-2008 13:00:00 Yes
             3        444 01-01-2008 00:00:00 01-01-2008 08:00:00 01-01-2008 09:00:00 NoIt's basically saying that there's an overlap between id 1 and id 2 (8-10 and 10-12), which is incorrect. I ran the inner query by itself:
    SQL> select lead( start_time, 1 ) over ( partition by emp_id order by start_time ) next_date,
      2                   lag( start_time, 1 ) over ( partition by emp_id order by start_time ) prev_date,
      3                   start_time, end_time, emp_id, date_worked, id
      4            from   test;
    NEXT_DATE           PREV_DATE           START_TIME          END_TIME                EMP_ID DATE_WORKED                 ID
    01-01-2008 08:00:00                     01-01-2008 07:00:00 01-01-2008 08:00:00        333 01-01-2008 00:00:00          5
    01-01-2008 10:00:00 01-01-2008 07:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00        333 01-01-2008 00:00:00          1
    01-01-2008 11:00:00 01-01-2008 08:00:00 01-01-2008 10:00:00 01-01-2008 12:00:00        333 01-01-2008 00:00:00          2
                        01-01-2008 10:00:00 01-01-2008 11:00:00 01-01-2008 13:00:00        333 01-01-2008 00:00:00          4
                                            01-01-2008 08:00:00 01-01-2008 09:00:00        444 01-01-2008 00:00:00          3with this data, I can't seem to find a way to conditional test in order to print my overlap column with "yes" or "no" accordingly.
    am I missing something?

  • Custom window in analytic function

    SELECT  device_id,
            case_id,
            value,
            fo_value,
            nomination,
            symbol,
            cur_id,
            time,
            data_type,
            COALESCE (
               VALUE,
               LAST_VALUE (
                  VALUE IGNORE NULLS
                  OVER (PARTITION BY device_id, cur_id, nomination
                        ORDER BY time
                        ROWS UNBOUNDED PRECEDING)
               + SUM(fo_value)
                    OVER (PARTITION BY device_id, cur_id, nomination
                          ORDER BY time
                          ROWS UNBOUNDED PRECEDING)
               AS val 
    FROM tab  
    DEVICE_ID     CASE_ID     VALUE     FO_VALUE     NOMINATION     SYMBOL     CUR_ID     TIME     DATA_TYPE     VAL
    8744     4901          -23     20     PLN     1     2009-08-25 11:00:00.000000     F     -48
    8744     4901          -2     20     PLN     1     2009-08-25 07:00:00.000000     F     -25
    8744     4901     100     -13     20     PLN     1     2009-08-24 23:00:00.000000     I     100
    8744     4901          -6     20     PLN     1     2009-08-24 17:00:00.000000     F     45
    8744     4901          -5     20     PLN     1     2009-08-24 14:00:00.000000     F     51
    8744     4901          -5     20     PLN     1     2009-08-24 11:00:00.000000     F     56VAL column is defined as last VALUE from which there was substracted cummulative sum of FO_VALUE column.
    Every record with data_type = 'I' has some number in VALUE column. What I need is to define window in expression that counts sum of FO_VALUE which adds only the values from last NON-NULL VALUE column - currently query substracts all the values in partition.
    I need something like window from last NON-NULL in VALUE column row to current row
    Desired output should look like this:
    DEVICE_ID     CASE_ID     VALUE     FO_VALUE     NOMINATION     SYMBOL     CUR_ID     TIME     DATA_TYPE     VAL
    8744     4901          -23     20     PLN     1     2009-08-25 11:00:00.000000     F     62
    8744     4901          -2     20     PLN     1     2009-08-25 07:00:00.000000     F     85
    8744     4901     100     -13     20     PLN     1     2009-08-24 23:00:00.000000     I     87
    8744     4901          -6     20     PLN     1     2009-08-24 17:00:00.000000     F     45
    8744     4901          -5     20     PLN     1     2009-08-24 14:00:00.000000     F     51
    8744     4901          -5     20     PLN     1     2009-08-24 11:00:00.000000     F     56I'd be very appeciated for any suggestions.

    Hi,
    Sorry, I don't understand the problem.
    In particular, I don't see how you get the vals (56, 51, 45) for the earlier times. It looks like you should get NULL for val in the ealiest 3 rows. Can you explain how you get those numbers?
    Is it possible for a partition (device_id, cur_id, nomination) to have 2 or more rows where value is not NULL? If so, please post an example of the results you would want.
    Rather than adjusting ROWS ... to get the results you want, it might be easier to adjust the PARTITION BY ...
    For example, this gets the results you want on and after the row where value is not NULL:
    WITH     got_grp_num
    AS
         SELECT  device_id, case_id, value, fo_value, nomination, symbol, cur_id, time, data_type,
              COUNT (value) OVER ( PARTITION BY device_id, cur_id, nomination
                                               ORDER BY         time
                           )         AS grp_num
         FROM     tab
    SELECT  device_id, case_id, value, fo_value, nomination, symbol, cur_id, time, data_type,
            LAST_VALUE (value IGNORE NULLS) OVER ( PARTITION BY  device_id, cur_id, nomination, grp_num
                                                      ORDER BY      time
             + SUM (fo_value)           OVER ( PARTITION BY  device_id, cur_id, nomination, grp_num
                                                 ORDER BY      time
                                  )           AS val 
    FROM        got_grp_num  
    ORDER BY  device_id, cur_id, nomination,
                 time                         DESC
    ;As you can see, there is a new column in the PARTITION BY clauses that compute val. The new column is grp_num, which has a new value whenever there is a non-null value.
    Edited by: Frank Kulash on Aug 28, 2009 1:27 PM

  • [8i] Subquery vs Multiple Analytic Functions

    Does anyone have an idea which is better performance-wise?
    I have a query that is 3 layers deep already with sub-queries. In the topmost level, I have a choice. I can calculate one analytic function twice, and one analytic function three times, or I can make the topmost level into a subquery, and calculate each analytic function only once.
    In case it matters for this problem, this query is running on an 8i database.
    A simplified example:
    CREATE TABLE     my_data
    (     order_no     CHAR(10)
    ,     seq_nbr          CHAR(4)
    ,     area_id          CHAR(4)
    ,     start_date     DATE
    ,     unit_time     NUMBER(7,2)
    INSERT INTO my_data VALUES ('0000567890','0010','A001',TO_DATE('05/01/2000','mm/dd/yyyy'),0.34);
    INSERT INTO my_data VALUES ('0000567890','0020','A001',TO_DATE('05/02/2000','mm/dd/yyyy'),0.78);
    INSERT INTO my_data VALUES ('0000567890','0030','A002',TO_DATE('05/03/2000','mm/dd/yyyy'),0.91);
    INSERT INTO my_data VALUES ('0000567890','0040','A003',TO_DATE('05/03/2000','mm/dd/yyyy'),0.27);
    INSERT INTO my_data VALUES ('0000123456','0010','A001',TO_DATE('04/01/2001','mm/dd/yyyy'),0.39);
    INSERT INTO my_data VALUES ('0000123456','0020','A001',TO_DATE('04/02/2001','mm/dd/yyyy'),0.98);
    INSERT INTO my_data VALUES ('0000123456','0030','A002',TO_DATE('04/03/2001','mm/dd/yyyy'),0.77);
    INSERT INTO my_data VALUES ('0000123456','0040','A003',TO_DATE('04/03/2001','mm/dd/yyyy'),0.28);
    INSERT INTO my_data VALUES ('0000123123','0010','A001',TO_DATE('12/01/2001','mm/dd/yyyy'),0.31);
    INSERT INTO my_data VALUES ('0000123123','0020','A001',TO_DATE('12/02/2001','mm/dd/yyyy'),0.86);
    INSERT INTO my_data VALUES ('0000123123','0030','A002',TO_DATE('12/03/2001','mm/dd/yyyy'),0.82);
    INSERT INTO my_data VALUES ('0000123123','0040','A003',TO_DATE('12/03/2001','mm/dd/yyyy'),0.23);
    INSERT INTO my_data VALUES ('0000111111','0010','A001',TO_DATE('06/01/2002','mm/dd/yyyy'),0.29);
    INSERT INTO my_data VALUES ('0000111111','0020','A001',TO_DATE('06/02/2002','mm/dd/yyyy'),0.84);
    INSERT INTO my_data VALUES ('0000111111','0030','A002',TO_DATE('06/03/2002','mm/dd/yyyy'),0.78);
    INSERT INTO my_data VALUES ('0000111111','0040','A003',TO_DATE('06/03/2002','mm/dd/yyyy'),0.26);
    INSERT INTO my_data VALUES ('0000654321','0010','A001',TO_DATE('05/01/2003','mm/dd/yyyy'),0.28);
    INSERT INTO my_data VALUES ('0000654321','0020','A001',TO_DATE('05/02/2003','mm/dd/yyyy'),0.88);
    INSERT INTO my_data VALUES ('0000654321','0030','A002',TO_DATE('05/03/2003','mm/dd/yyyy'),0.75);
    INSERT INTO my_data VALUES ('0000654321','0040','A003',TO_DATE('05/03/2003','mm/dd/yyyy'),0.25);My choices for the example are:
    SELECT     area_id
    ,     period_start
    ,     period_end
    ,     AVG(tot_area_unit_hrs)     
         OVER     (
              PARTITION BY     area_id
              ORDER BY     period_start
              RANGE BETWEEN     period_end - period_start     PRECEDING
                    AND     CURRENT ROW
         STDDEV(tot_area_unit_hrs)     
         OVER     (
              PARTITION BY     area_id
              ORDER BY     period_start
              RANGE BETWEEN     period_end - period_start     PRECEDING
                    AND     CURRENT ROW
              )           AS lo_unit_time
    ,     AVG(tot_area_unit_hrs)     
         OVER     (
              PARTITION BY     area_id
              ORDER BY     period_start
              RANGE BETWEEN     period_end - period_start     PRECEDING
                    AND     CURRENT ROW
              )               AS avg_unit_time
    ,     AVG(tot_area_unit_hrs)     
         OVER     (
              PARTITION BY     area_id
              ORDER BY     period_start
              RANGE BETWEEN     period_end - period_start     PRECEDING
                    AND     CURRENT ROW
              )               +
         STDDEV(tot_area_unit_hrs)     
         OVER     (
              PARTITION BY     area_id
              ORDER BY     period_start
              RANGE BETWEEN     period_end - period_start     PRECEDING
                    AND     CURRENT ROW
              )           AS hi_unit_time
    FROM     (
         SELECT     order_no
         ,     area_id
         ,     ADD_MONTHS(MIN(start_date),-24)+1     AS period_start
         ,     MIN(start_date)                    AS period_end
         ,     SUM(unit_time)                    AS tot_area_unit_hrs
         FROM     my_data
         GROUP BY     order_no
         ,          area_id
    ORDER BY     area_id
    ,          period_end
    ;or
    SELECT     area_id
    ,     period_start
    ,     period_end
    ,     avg_unit_time - stdev_unit_time     AS lo_unit_time
    ,     avg_unit_time
    ,     avg_unit_time + stdev_unit_time     AS hi_unit_time
    FROM     (
         SELECT     area_id
         ,     period_start
         ,     period_end
         ,     STDDEV(tot_area_unit_hrs)     
              OVER     (
                   PARTITION BY     area_id
                   ORDER BY     period_start
                   RANGE BETWEEN     period_end - period_start     PRECEDING
                         AND     CURRENT ROW
                   )           AS stdev_unit_time
         ,     AVG(tot_area_unit_hrs)     
              OVER     (
                   PARTITION BY     area_id
                   ORDER BY     period_start
                   RANGE BETWEEN     period_end - period_start     PRECEDING
                         AND     CURRENT ROW
                   )               AS avg_unit_time
         FROM     (
              SELECT     order_no
              ,     area_id
              ,     ADD_MONTHS(MIN(start_date),-24)+1     AS period_start
              ,     MIN(start_date)                    AS period_end
              ,     SUM(unit_time)                    AS tot_area_unit_hrs
              FROM     my_data
              GROUP BY     order_no
              ,          area_id
    ORDER BY     area_id
    ,          period_end
    ;My gut instinct would be that the 2nd option is faster (with the sub-query), but before I try this on my actual data set which is much larger, I'd like a second opinion. I don't want to accidentally start running a "neverending" query.

    Sorry for the delay in response here... I was busy deleting 39 GB of trace files, because some silly person (hangs head in shame) accidentally set TRACE_LEVEL_CLIENT=SUPPORT months ago and forgot to turn it off, and didn't notice until her hard drive was full and she couldn't save a file.....
    Anyway...
    @Dev
    For the real query...
    option 1 explain plan:
    OPERATION          OPTIONS          OBJECT_NODE   OBJECT_OWNER   OBJECT_NAME   OBJECT_INSTANCE   OBJECT_TYPE   OPTIMIZER      ID   PARENT_ID   POSITION   COST   CARDINALITY   BYTES    
    SELECT STATEMENT   REMOTE                                                                                      HINT: CHOOSE   0                6076       6076   1             91       
    SORT               ORDER BY                                                                                                   1    0           1          6076   1             91       
    WINDOW             SORT                                                                                                       2    1           1                 1             91       
    SORT               GROUP BY                                                                                                   3    2           1          6076   1             91       
    FILTER                                                                                                                        4    3           1                                        
    NESTED LOOPS                                                                                                                  5    4           1          6071   1             91       
    TABLE ACCESS       FULL             DB8I.WORLD    ASCHEMA        DETAILS       2                                              6    5           1          6068   1             50       
    INDEX              RANGE SCAN       DB8I.WORLD    ASCHEMA        ORDERS_IX3                      UNIQUE        ANALYZED       7    5           2          3      141930        5819130  
    TABLE ACCESS       BY INDEX ROWID   DB8I.WORLD    ASCHEMA        DETAILS       3                                              8    4           2          7      1             44       
    INDEX              RANGE SCAN       DB8I.WORLD    ASCHEMA        DETAILS_IX1                     NON-UNIQUE    ANALYZED       9    8           1          3      1                       option 2 explain plan:
    OPERATION          OPTIONS    OBJECT_NODE   OBJECT_OWNER   OBJECT_NAME   OBJECT_INSTANCE   OBJECT_TYPE   OPTIMIZER      ID   PARENT_ID   POSITION   COST   CARDINALITY   BYTES  
    SELECT STATEMENT                                                                                         HINT: CHOOSE   0                2777       2777   96            14208  
    SORT               ORDER BY                                                                                             1    0           1          2777   96            14208  
    VIEW                                        LOCALUSER                    1                                              2    1           1          2776   96            14208  
    WINDOW             SORT                                                                                                 3    2           1          2776   96            26400  
    HASH               GROUP BY                                                                                             4    3           1          2776   96            26400  
    FILTER                                                                                                                  5    4           1                                      
    REMOTE                        DB8I                                                         REMOTE                       6    5           1          1908   386           59830  
    REMOTE                        DB8I                         DETAILS                         REMOTE                       7    5           2          4      1             129     You should know, in order to get explain plan on these queries, I have to run them via a database link to the 8i database through XE 10g on my local machine, as I don't have access to run explain plan on the remote database itself. I've never seen my local user name appear before in an explain plan run this way, but it did in the one for option #2 (subquery), so I'd guess that wouldn't be the explain plan I'd get if I ran it just in the 8i database. I also find it really odd that the ORDERS table doesn't seem to be referenced in the 2nd explain plan... I do think that's still going to be my best option though, so I'm going to try it and hope it doesn't take too long.
    @Frank Kulash
    Agreed. That's what I'll try, and I also think that I can't put the analytic function in with the aggregates, without having to do some additional computations in that sub-query, which I think would defeat the purpose of putting them there in the first place.

  • COUNT(DISTINCT) WITH ORDER BY in an analytic function

    -- I create a table with three fields: Name, Amount, and a Trans_Date.
    CREATE TABLE TEST
    NAME VARCHAR2(19) NULL,
    AMOUNT VARCHAR2(8) NULL,
    TRANS_DATE DATE NULL
    -- I insert a few rows into my table:
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '20', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/02/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '21', TO_DATE('06/03/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '68', TO_DATE('06/04/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '110', TO_DATE('06/05/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Anna', '20', TO_DATE('06/06/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '43', TO_DATE('06/01/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '77', TO_DATE('06/02/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '221', TO_DATE('06/03/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '43', TO_DATE('06/04/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    INSERT INTO TEST ( TEST.NAME, TEST.AMOUNT, TEST.TRANS_DATE ) VALUES ( 'Bill', '73', TO_DATE('06/05/2005 08:00:00 PM', 'MM/DD/YYYY HH12:MI:SS PM') );
    commit;
    /* I want to retrieve all the distinct count of amount for every row in an analytic function with COUNT(DISTINCT AMOUNT) sorted by name and ordered by trans_date where I get only calculate for the last four trans_date for each row (i.e., for the row "Anna 110 6/5/2005 8:00:00.000 PM," I only want to look at the previous dates from 6/2/2005 to 6/5/2005 and get the distinct count of how many amounts there are different for Anna). Note, I cannot use the DISTINCT keyword in this query because it doesn't work with the ORDER BY */
    select NAME, AMOUNT, TRANS_DATE, COUNT(/*DISTINCT*/ AMOUNT) over ( partition by NAME
    order by TRANS_DATE range between numtodsinterval(3,'day') preceding and current row ) as COUNT_AMOUNT
    from TEST t;
    This is the results I get if I just count all the AMOUNT without using distinct:
    NAME     AMOUNT     TRANS_DATE     COUNT_AMOUNT
    Anna 110 6/1/2005 8:00:00.000 PM     2
    Anna 20 6/1/2005 8:00:00.000 PM     2
    Anna 110     6/2/2005 8:00:00.000 PM     3
    Anna 21     6/3/2005 8:00:00.000 PM     4
    Anna 68     6/4/2005 8:00:00.000 PM     5
    Anna 110     6/5/2005 8:00:00.000 PM     4
    Anna 20     6/6/2005 8:00:00.000 PM     4
    Bill 43     6/1/2005 8:00:00.000 PM     1
    Bill 77     6/2/2005 8:00:00.000 PM     2
    Bill 221     6/3/2005 8:00:00.000 PM     3
    Bill 43     6/4/2005 8:00:00.000 PM     4
    Bill 73     6/5/2005 8:00:00.000 PM     4
    The COUNT_DISTINCT_AMOUNT is the desired output:
    NAME     AMOUNT     TRANS_DATE     COUNT_DISTINCT_AMOUNT
    Anna     110     6/1/2005 8:00:00.000 PM     1
    Anna     20     6/1/2005 8:00:00.000 PM     2
    Anna     110     6/2/2005 8:00:00.000 PM     2
    Anna     21     6/3/2005 8:00:00.000 PM     3
    Anna     68     6/4/2005 8:00:00.000 PM     4
    Anna     110     6/5/2005 8:00:00.000 PM     3
    Anna     20     6/6/2005 8:00:00.000 PM     4
    Bill     43     6/1/2005 8:00:00.000 PM     1
    Bill     77     6/2/2005 8:00:00.000 PM     2
    Bill     221     6/3/2005 8:00:00.000 PM     3
    Bill     43     6/4/2005 8:00:00.000 PM     3
    Bill     73     6/5/2005 8:00:00.000 PM     4
    Thanks in advance.

    you can try to write your own udag.
    here is a fake example, just to show how it "could" work. I am here using only 1,2,4,8,16,32 as potential values.
    create or replace type CountDistinctType as object
       bitor_number number,
       static function ODCIAggregateInitialize(sctx IN OUT CountDistinctType) 
         return number,
       member function ODCIAggregateIterate(self IN OUT CountDistinctType, 
         value IN number) return number,
       member function ODCIAggregateTerminate(self IN CountDistinctType, 
         returnValue OUT number, flags IN number) return number,
        member function ODCIAggregateMerge(self IN OUT CountDistinctType,
          ctx2 IN CountDistinctType) return number
    create or replace type body CountDistinctType is 
    static function ODCIAggregateInitialize(sctx IN OUT CountDistinctType) 
    return number is 
    begin
       sctx := CountDistinctType('');
       return ODCIConst.Success;
    end;
    member function ODCIAggregateIterate(self IN OUT CountDistinctType, value IN number)
      return number is
      begin
        if (self.bitor_number is null) then
          self.bitor_number := value;
        else
          self.bitor_number := self.bitor_number+value-bitand(self.bitor_number,value);
        end if;
        return ODCIConst.Success;
      end;
      member function ODCIAggregateTerminate(self IN CountDistinctType, returnValue OUT
      number, flags IN number) return number is
      begin
        returnValue := 0;
        for i in 0..log(2,self.bitor_number) loop
          if (bitand(power(2,i),self.bitor_number)!=0) then
            returnValue := returnValue+1;
          end if;
        end loop;
        return ODCIConst.Success;
      end;
      member function ODCIAggregateMerge(self IN OUT CountDistinctType, ctx2 IN
      CountDistinctType) return number is
      begin
        return ODCIConst.Success;
      end;
      end;
    CREATE or REPLACE FUNCTION CountDistinct (n number) RETURN number 
    PARALLEL_ENABLE AGGREGATE USING CountDistinctType;
    drop table t;
    create table t as select rownum r, power(2,trunc(dbms_random.value(0,6))) p from all_objects;
    SQL> select r,p,countdistinct(p) over (order by r) d from t where rownum<10 order by r;
             R          P          D
             1          4          1
             2          1          2
             3          8          3
             4         32          4
             5          1          4
             6         16          5
             7         16          5
             8          4          5
             9          4          5buy some good book if you want to start at writting your own "distinct" algorythm.
    Message was edited by:
    Laurent Schneider
    a simpler but memory killer algorithm would use a plsql table in an udag and do the count(distinct) over that table to return the value

  • Analytic function to count rows based on Special criteria

    Hi
    I have the following query with analytic function but wrong results on the last column COUNT.
    Please help me to achive the required result.Need to change the way how I select the last column.
    1)I am getting the output order by b.sequence_no column . This is a must.
    2)COUNT Column :
    I don't want the total count based on thor column hence there is no point in grouping by that column.
    The actual requirement to achieve COUNT is:
    2a -If in the next row, if either the THOR and LOC combination changes to a new value, then COUNT=1
    (In other words, if it is different from the following row)
    2b-If the values of THOR and LOC repeats in the following row, then the count should be the total of all those same value rows until the rows become different.
    (In this case 2b-WHERE THE ROWS ARE SAME- also I only want to show these same rows only once. This is shown in the "MY REQUIRED OUTPUT) .
    My present query:
    select    r.name REGION ,
              p.name PT,
              do.name DELOFF,
              ro.name ROUTE,
    decode(th.thorfare_name,'OSIUNKNOWN',NULL,th.thorfare_name)
               THOR,
             l.name LOC ,
              b.sequence_no SEQ,
               CASE WHEN th.thorfare_name = LAG (th.thorfare_name)
                OVER (order by b.sequence_no)
                or th.thorfare_name = LEAD (th.thorfare_name)
                OVER (order by b.sequence_no)
                THEN  COUNT(b.sequence_no) OVER (partition by r.name,th.thorfare_name,l.name order BY b.sequence_no
              ELSE 1
              END COUNT
    from   t_regions r,t_post_towns p,t_delivery_offices do, t_routes ro, t_counties c,t_head_offices ho,
    t_buildings b,t_thoroughfares th,t_localities l
    where   th.thorfare_id = b.thorfare_id
    and    nvl(b.invalid,'N')='N'
    and    b.route_id=ro.route_id(+)
    and    b.locality_id =l.locality_id(+)
    and    ro.delivery_office_id=do.delivery_office_id(+)
    and    do.post_town_id = p.post_town_id(+)
    and    p.ho_id=ho.ho_id(+)
    and     ho.county_id = c.county_id(+)
    and     c.region_id = r.region_id(+)
    and    r.name='NAAS'
    and    do.DELIVERY_OFFICE_id= &&DELIVERY_OFFICE_id
    and    ro.route_id=3405
    group by r.name,p.name,do.name,ro.name,th.thorfare_name,l.name,b.sequence_no
    ORDER BY ro.name,b.sequence_no;My incorrect output[PART OF DATA]:
    >
    REGION     PT DELOFF ROUTE     THOR LOC SEQ COUNT
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 1 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 2 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 PRIMHILL CEL 4 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 5 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 THEGROVE CEL 2 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 7 3
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 8 4
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 9 5
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 10 6
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 11 7
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 12 8
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 15 2
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 19 3
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 24 4
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 29 5
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 34 6
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 39 7
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 42 2
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 PRIMHILL CEL 43 2
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 PRIMHILL CEL 44 3
    My required output[PART OF DATA]-Please compare with the above.:
    >
    REGION     PT DELOFF ROUTE     THOR LOC COUNT
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 PRIMHILL CEL 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 THEGROVE CEL 1
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 NEWTOWNRD CEL 6
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 DUBLINRD CEL 7
    NAAS     NAAS MAYNOOTH     MAYNOOTHR010 PRIMHILL CEL 2
    NOTE :Count as 1 is correctly coming.
    But where there is same rows and I want to take the total count on them, I am not getting.
    Pls pls help.
    Thanks
    Edited by: Krithi on 04-Nov-2010 05:28

    Nicosa wrote:
    Hi,
    Can you give us some sample data (create table + inserts orders) to play with ?
    Considering your output, I'm not even sure you need analytic count.Yes sure.
    I am describing the query again here with 3 tables now to make this understand better.
    Given below are the create table statements and insert statements for these 3 tables.
    These tables are - BULDINGSV,THORV and LOCV
    CREATE TABLE BUILDINGSV
      BUILDING_ID                  NUMBER(10)       NOT NULL,
      INVALID                      VARCHAR2(1 BYTE),
      ROUTE_ID                     NUMBER(10),
      LOCALITY_ID                  NUMBER(10),
      SEQUENCE_NO                  NUMBER(4),
      THORFARE_ID                  NUMBER(10) NOT NULL
    CREATE TABLE THORV
      THORFARE_ID            NUMBER(10)             NOT NULL,
      THORFARE_NAME          VARCHAR2(40 BYTE)      NOT NULL
    CREATE TABLE LOCV
      LOCALITY_ID            NUMBER(10)             NOT NULL,
      NAME                   VARCHAR2(40 BYTE)      NOT NULL);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002372, 'N', 3405, 37382613, 5, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002363, 'N', 3405, 37382613, 57, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002362, 'N', 3405, 37382613, 56, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002360, 'N', 3405, 37382613, 52, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002358, 'N', 3405, 37382613, 1, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002240, 'N', 3405, 37382613, 6, 9002284);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002229, 'N', 3405, 37382613, 66, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002228, 'N', 3405, 37382613, 65, 35291872);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002226, 'N', 3405, 37382613, 62, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002222, 'N', 3405, 37382613, 43, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002217, 'N', 3405, 37382613, 125, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002221, 'N', 3405, 37382613, 58, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002214, 'N', 3405, 37382613, 128, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33363182, 'N', 3405, 37382613, 114, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33363185, 'N', 3405, 37382613, 115, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002371, 'N', 3405, 37382613, 2, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003329, 'N', 3405, 37382613, 415, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002359, 'N', 3405, 37382613, 15, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002224, 'N', 3405, 37382613, 61, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003318, 'N', 3405, 37382613, 411, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003326, 'N', 3405, 37382613, 412, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003327, 'N', 3405, 37382613, 413, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003328, 'N', 3405, 37382613, 414, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003330, 'N', 3405, 37382613, 416, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003331, 'N', 3405, 37382613, 417, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27003332, 'N', 3405, 37382613, 410, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27004795, 'N', 3405, 37382613, 514, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (27004807, 'N', 3405, 37382613, 515, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (59002227, 'N', 3405, 37382613, 64, 35291872);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33230805, 'N', 3405, 37382613, 44, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33231027, 'N', 3405, 37382613, 7, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33231058, 'N', 3405, 37382613, 9, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33231078, 'N', 3405, 37382613, 10, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33231087, 'N', 3405, 37382613, 11, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33231093, 'N', 3405, 37382613, 12, 9002375);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (33229890, 'N', 3405, 37382613, 55, 9002364);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561996, 'N', 3405, 34224751, 544, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561997, 'N', 3405, 34224751, 543, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561998, 'N', 3405, 34224751, 555, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562000, 'N', 3405, 34224751, 541, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562001, 'N', 3405, 34224751, 538, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562028, 'N', 3405, 35417256, 525, 0);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562031, 'N', 3405, 35417256, 518, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562032, 'N', 3405, 35417256, 519, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562033, 'N', 3405, 35417256, 523, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561939, 'N', 3405, 34224751, 551, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561940, 'N', 3405, 34224751, 552, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561941, 'N', 3405, 34224751, 553, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561942, 'N', 3405, 35417256, 536, 0);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561943, 'N', 3405, 35417256, 537, 0);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561970, 'N', 3405, 35417256, 522, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561972, 'N', 3405, 35417256, 527, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561974, 'N', 3405, 35417256, 530, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561975, 'N', 3405, 35417256, 531, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561980, 'N', 3405, 34224751, 575, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561981, 'N', 3405, 34224751, 574, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561983, 'N', 3405, 34224751, 571, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561984, 'N', 3405, 34224751, 570, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561985, 'N', 3405, 34224751, 568, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561986, 'N', 3405, 34224751, 567, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561987, 'N', 3405, 34224751, 566, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561989, 'N', 3405, 34224751, 563, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561990, 'N', 3405, 34224751, 562, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561991, 'N', 3405, 34224751, 560, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561992, 'N', 3405, 34224751, 559, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561993, 'N', 3405, 34224751, 558, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561994, 'N', 3405, 34224751, 548, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80561995, 'N', 3405, 34224751, 546, 35417360);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562160, 'N', 3405, 37382613, 139, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562161, 'N', 3405, 37382613, 140, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562162, 'N', 3405, 37382613, 141, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562163, 'N', 3405, 37382613, 142, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562164, 'N', 3405, 37382613, 143, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562165, 'N', 3405, 37382613, 145, 35291878);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562166, 'N', 3405, 37382613, 100, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562167, 'N', 3405, 37382613, 102, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562171, 'N', 3405, 37382613, 107, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562172, 'N', 3405, 37382613, 108, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562174, 'N', 3405, 37382613, 110, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562175, 'N', 3405, 37382613, 111, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562176, 'N', 3405, 37382613, 112, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562177, 'N', 3405, 37382613, 113, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562182, 'N', 3405, 37382613, 123, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562183, 'N', 3405, 37382613, 121, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562184, 'N', 3405, 37382613, 120, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562185, 'N', 3405, 37382613, 118, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562186, 'N', 3405, 37382613, 117, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562187, 'N', 3405, 37382613, 116, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562189, 'N', 3405, 37382613, 95, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562190, 'N', 3405, 37382613, 94, 35291883);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562213, 'N', 3405, 37382613, 89, 35291872);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (80562240, 'N', 3405, 35417256, 516, 35417271);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329559, 'N', 3405, 35329152, 443, 35329551);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329560, 'N', 3405, 35329152, 444, 35329551);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329562, 'N', 3405, 35329152, 446, 35329551);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329109, 'N', 3405, 35329152, 433, 35329181);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329169, 'N', 3405, 35329152, 434, 35329181);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329557, 'N', 3405, 35329152, 441, 35329551);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329558, 'N', 3405, 35329152, 442, 35329551);
    Insert into BUILDINGSV
       (BUILDING_ID, INVALID, ROUTE_ID, LOCALITY_ID, SEQUENCE_NO, THORFARE_ID)
    Values
       (35329191, 'N', 3405, 35329152, 436, 35329181);
    COMMIT;
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (0, 'OSIUNKNOWN');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (9002284, 'THE GROVE');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (9002364, 'DUBLIN ROAD');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (9002375, 'NEWTOWN ROAD');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35291872, 'HAZELHATCH ROAD');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35291878, 'SIMMONSTOWN PARK');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35291883, 'PRIMROSE HILL');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35329181, 'THE COPSE');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35329213, 'THE COURT');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35329529, 'THE CRESCENT');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35329551, 'THE LAWNS');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35329580, 'THE DRIVE');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35417271, 'TEMPLEMILLS COTTAGES');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (35417360, 'CHELMSFORD');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (36500023, 'THE CLOSE');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (36500101, 'THE GREEN');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37375569, 'THE DOWNS');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37375595, 'THE PARK');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37375754, 'THE AVENUE');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37375781, 'THE VIEW');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37376046, 'THE CRESCENT');
    Insert into THORV
       (THORFARE_ID, THORFARE_NAME)
    Values
       (37376048, 'THE GLADE');
    COMMIT;
    Insert into LOCV
       (LOCALITY_ID, NAME)
    Values
       (34224751, 'SIMMONSTOWN');
    Insert into LOCV
       (LOCALITY_ID, NAME)
    Values
       (35417256, 'TEMPLEMILLS');
    Insert into LOCV
       (LOCALITY_ID, NAME)
    Values
       (35329152, 'TEMPLE MANOR');
    Insert into LOCV
       (LOCALITY_ID, NAME)
    Values
       (37382613, 'CELBRIDGE');
    Insert into LOCV
       (LOCALITY_ID, NAME)
    Values
       (37375570, 'SAINT WOLSTAN''S ABBEY');
    COMMIT;
    ------------------------------------------------------------------------------Now the query with wrong result:
    select decode(th.thorfare_name,'OSIUNKNOWN',NULL,th.thorfare_name)
               THOR,
                l.name LOC,
                b.sequence_no SEQ,
               CASE WHEN th.thorfare_name = LAG (th.thorfare_name)
                OVER (order by b.sequence_no)
                or th.thorfare_name = LEAD (th.thorfare_name)
                OVER (order by b.sequence_no)
                THEN  COUNT(b.sequence_no) OVER (partition by th.thorfare_name,l.name order BY b.sequence_no
              ELSE 1
              END COUNT   from BUILDINGSV b,THORV th,LOCV l                 
    where   th.thorfare_id = b.thorfare_id
    and    nvl(b.invalid,'N')='N'
    and    b.route_id=3405
    and    b.locality_id =l.locality_id(+)
    order by b.sequence_no;The query result -WRONG (only first few lines)
    THOR                        LOC        SEQ    COUNT
    DUBLIN ROAD     CELBRIDGE    1     1
    NEWTOWN ROAD     CELBRIDGE        2     1
    NEWTOWN ROAD     CELBRIDGE        5     2
    THE GROVE     CELBRIDGE        6     1
    NEWTOWN ROAD     CELBRIDGE        7     3
    NEWTOWN ROAD     CELBRIDGE        9     4
    NEWTOWN ROAD     CELBRIDGE       10     5
    NEWTOWN ROAD     CELBRIDGE       11     6
    NEWTOWN ROAD     CELBRIDGE       12     7
    DUBLIN ROAD     CELBRIDGE       15     1
    PRIMROSE HILL     CELBRIDGE       43     1
    PRIMROSE HILL     CELBRIDGE       44     2
    DUBLIN ROAD     CELBRIDGE       52     3
    DUBLIN ROAD     CELBRIDGE       55     4
    DUBLIN ROAD     CELBRIDGE       56     5
    DUBLIN ROAD     CELBRIDGE       57     6
    DUBLIN ROAD     CELBRIDGE       58     7
    PRIMROSE HILL     CELBRIDGE       61     3
    PRIMROSE HILL     CELBRIDGE       62     4
    HAZELHATCH ROAD     CELBRIDGE       64     1
    HAZELHATCH ROAD     CELBRIDGE       65     2The query result -EXPECTED (only first few lines)
    THOR                     LOC     COUNT
    DUBLIN ROAD     CELBRIDGE      1
    NEWTOWN ROAD     CELBRIDGE      2
    THE GROVE     CELBRIDGE      1
    NEWTOWN ROAD     CELBRIDGE      5
    DUBLIN ROAD     CELBRIDGE      1
    PRIMROSE HILL     CELBRIDGE      2
    DUBLIN ROAD     CELBRIDGE      5
    PRIMROSE HILL     CELBRIDGE      2
    HAZELHATCH ROAD     CELBRIDGE      2Please note, in the expected result, I only need 1 row but need to show the total count of rows until the names change.
    So the issues are
    1) the count column values are wrong in my query.
    2)I dont want to repeat the same rows(Please see EXPECTED output and compare it against the original)
    3)Want the output in exactly same way as in EXPECTED OUTPUT as I dont want to group by thor name(Eg. I dont want the count for all DUBLIN ROAD but I want to examine rows for the next one, if THOR/LOC combination is different in next row then COUNT=1 else COUNT=Count of no. of rows for that thor/loc combination until the combination change -So there are same value multiple rows which i need to show it in 1 row with the total count)
    I am explaining below this in more detail!!
    I only need 1 row per same THOR/LOC names coming multiple times but I need the count shown against that 1 row(i.e COUNT= how many rows with same thor/loc combination until THOR/LOC combo changes value).
    Then repeat the process until all rows are finished..
    If there is no multiple row with same THOR/LOC coming in the following row-i.e the following row is a different THOR/LOC combination, then the count for that row is 1.
    Hope this is clear.
    Is this doable?
    Thanks in advance.
    Edited by: Krithi on 04-Nov-2010 07:45
    Edited by: Krithi on 04-Nov-2010 07:45
    Edited by: Krithi on 04-Nov-2010 08:31

  • A function instead of UNBOUNDED PRECEDING (like "Last field with value=0")

    Hello,
    I have a table with many rows. The attributes of the table are code, month and value.
    For each code there are 12 months and 12 values.
    No I want to add the gaps between the months...
    Is it possible to count the following gaps between the different rows...?
    For example:
    Original table1:_
    code, month, value
    1,1,20
    1,2,0
    1,3,30
    1,4,0
    1,5,40
    1,6,0
    1,7,0
    1,8,20
    1,9,0
    1,10,10
    1,11,0
    1,12,0
    5,1,0
    5,2,20
    5,3,10
    description:*
    january value = 20
    february value = 0 (=>count this gap => new value 1 )
    march value = 30
    april value = 0 (=>count this gap => new value 1 )
    may value = 40
    june value = 0
    july value = 0 (=>count this two following gaps => new value 2 )
    agust value = 20
    september value = 0 (=>count this gap => new value 1 )
    october value = 10
    november value = 0
    december value = 0 (=>count this two following gaps => new value 2 )
    New target table:_
    code, month, value
    1,1,20
    1,2,*1*
    1,3,30
    1,4,*1*
    1,5,40
    1,6,0
    1,7,*2*
    1,8,20
    1,9,*1*
    1,10,10
    1,11,0
    1,12,*2*
    5,1,*1*
    5,2,20
    5,3,10
    I tried this code:
    select code, month
    sum(value) over (
    order by month
    rows between unbounded preceding and current row
    *) as final_value*
    from table1 order by month;
    This adds all following fields cumulative from beginning to current_row. But I need this adding only for the following gaps... then start with countin by 0.
    I need only the following like in the example on top. Maybe is there an other function like decode to count only the following gaps...!?
    A function instead of unbounded preceding....like "*Last field with value=0*" or something... ?
    Best regards,
    Tim

    TimB83 wrote:
    I have a table with many rows. The attributes of the table are code, month and value.
    For each code there are 12 months and 12 values.
    No I want to add the gaps between the months...
    Is it possible to count the following gaps between the different rows...?
    For example:
    Original table1:_
    code, month, value
    1,1,20
    1,2,0
    1,3,30
    1,4,0
    1,5,40
    1,6,0
    1,7,0
    1,8,20
    1,9,0
    1,10,10
    1,11,0
    1,12,0
    5,1,0
    5,2,20
    5,3,10
    description:*
    january value = 20
    february value = 0 (=>count this gap => new value 1 )
    march value = 30
    april value = 0 (=>count this gap => new value 1 )
    may value = 40
    june value = 0
    july value = 0 (=>count this two following gaps => new value 2 )
    agust value = 20
    september value = 0 (=>count this gap => new value 1 )
    october value = 10
    november value = 0
    december value = 0 (=>count this two following gaps => new value 2 )
    New target table:_
    code, month, value
    1,1,20
    1,2,*1*
    1,3,30
    1,4,*1*
    1,5,40
    1,6,0
    1,7,*2*
    1,8,20
    1,9,*1*
    1,10,10
    1,11,0
    1,12,*2*
    5,1,*1*
    5,2,20
    5,3,10
    ...Tim,
    you should post this question on the "SQL and PL/SQL" forum since it's a typical SQL question.
    There are probably much better ways to accomplish this and the guys over there will tell you, but here are two examples that might get you started:
    1. Pre-10g without MODEL clause
    with t as (
    select 1 as code, 1 as month, 20 as value from dual union all
    select 1 as code, 2 as month, 0 as value from dual union all
    select 1 as code, 3 as month, 30 as value from dual union all
    select 1 as code, 4 as month, 0 as value from dual union all
    select 1 as code, 5 as month, 40 as value from dual union all
    select 1 as code, 6 as month, 0 as value from dual union all
    select 1 as code, 7 as month, 0 as value from dual union all
    select 1 as code, 8 as month, 20 as value from dual union all
    select 1 as code, 9 as month, 0 as value from dual union all
    select 1 as code, 10 as month, 10 as value from dual union all
    select 1 as code, 11 as month, 0 as value from dual union all
    select 1 as code, 12 as month, 0 as value from dual union all
    select 5 as code, 1 as month, 0 as value from dual union all
    select 5 as code, 2 as month, 20 as value from dual union all
    select 5 as code, 3 as month, 10 as value from dual
    r1 as (
    select
            case
            when value = 0
            then 1
            else 0
            end as is_gap
          , case
            when value != 0
            then rownum
            else null
            end as grp_info
          , code
          , month
          , value
    from
            t
    r2 as (
    select
            last_value(grp_info ignore nulls) over (partition by code order by month) as grp
          , is_gap
          , code
          , month
          , value
    from
            r1
    select
            code
          , month
          , case
            when value = 0
            and (lead(value) over (partition by code order by month) != 0 or
                 lead(value) over (partition by code order by month) is null)
            then sum(is_gap) over (partition by code, grp)
            else value
            end as value
    from r2;2. 10g and later with MODEL clause
    with t as (
    select 1 as code, 1 as month, 20 as value from dual union all
    select 1 as code, 2 as month, 0 as value from dual union all
    select 1 as code, 3 as month, 30 as value from dual union all
    select 1 as code, 4 as month, 0 as value from dual union all
    select 1 as code, 5 as month, 40 as value from dual union all
    select 1 as code, 6 as month, 0 as value from dual union all
    select 1 as code, 7 as month, 0 as value from dual union all
    select 1 as code, 8 as month, 20 as value from dual union all
    select 1 as code, 9 as month, 0 as value from dual union all
    select 1 as code, 10 as month, 10 as value from dual union all
    select 1 as code, 11 as month, 0 as value from dual union all
    select 1 as code, 12 as month, 0 as value from dual union all
    select 5 as code, 1 as month, 0 as value from dual union all
    select 5 as code, 2 as month, 20 as value from dual union all
    select 5 as code, 3 as month, 10 as value from dual
    select
             code
           , month
           , value
    from
             t
    model
    partition by (code)
    dimension by (month)
    measures (value, 0 as gap_cnt)
    rules (
      gap_cnt[any] order by month =
      case
      when value[cv() - 1] = 0
      then gap_cnt[cv() - 1] + 1
      else 0
      end,
      value[any] order by month =
      case
      when value[cv()] = 0 and presentv(value[cv() + 1], value[cv() + 1], 1) != 0
      then presentv(gap_cnt[cv() + 1], gap_cnt[cv() + 1], gap_cnt[cv()] + 1)
      else value[cv()]
      end
    );Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

Maybe you are looking for

  • How to move ALL my iTunes stuff to a new installation...

    Hi there! I have an iTunes library with songs, videos, and PDFs and I want to back it up and move it to my new computer. So I have two partitions on my HDD... I keep all the stuff in a folder on the D:. I then format the C: drive, move the "iTunes" f

  • Switching off summarization of postings from T&E to FI- URGENT

    HI All This is a Statutory requirement for Poland 1.In PR05 When the Expense types are Same but appear as 2 different line items ( e.g claimant going from Mumbai too Pune and then from Pune to Nasik there is two entries but the Expense type used is t

  • Photo orientation when sending via email

    When I email photos they are displayed in landscape orientation when viewed on the computer but are properly displayed when viewed on the iPhone. Is anyone else having this problem or know how to fix it?

  • Why Reader X AND Reader 9?

    The only reason I can imagine for the installation of Reader X to not automatically Uninstall or Overlay the existing Reader 9, would be that Reader 9 has some functionality that Reader X lacks. I cannot find anything on the Adobe site that addresses

  • IC Issue

    Hi All, I am facing one issue related to posting of AP document for Intercompany Invoice. The IDOC (Status 51) for AP side is in error because of system is asking for Trading Partner for GL Account because of Substitution rule written. Now My issue i