Analytic function question

I have been trying to fix this since yesterday ad I am close, here is the question
CREATE TABLE P_X_STG
  PID  NUMBER,
  EID  VARCHAR2(10 BYTE)
CREATE TABLE TAB_C
  EID  VARCHAR2(10 BYTE),
  X    NUMBER
SET DEFINE OFF;
Insert into P_X_STG
   (PID, EID)
Values
   (1, 'e3');
Insert into P_X_STG
   (PID, EID)
Values
   (1, 'e1');
Insert into P_X_STG
   (PID, EID)
Values
   (1, 'e2');
Insert into P_X_STG
   (PID, EID)
Values
   (2, 'e3');
Insert into P_X_STG
   (PID, EID)
Values
   (2, 'e4');
Insert into P_X_STG
   (PID, EID)
Values
   (3, 'e5');
COMMIT;
SET DEFINE OFF;
Insert into TAB_C
   (EID, X)
Values
   ('e1', 100);
Insert into TAB_C
   (EID, X)
Values
   ('e3', 300);
Insert into TAB_C
   (X)
Values
   (400);
COMMIT;we match both the tables by eid
if the eid matches, get corresponding x information
if a pid has multiple different eids, for matching eid, get corresponding x information, but for non matching, simply put a NULL to x
for matching eids, print "ematch", for non matchig eids, print "pmatch"
in the below query, for non matching eids, we copy x information from matching ones, can someone help me substitute tha with Null
SELECT pid,
            eid,
            x,
            ematch
       FROM (  SELECT p.pid,
                      p.eid,
                      CASE
                         WHEN p.eid = c.eid THEN c.x
                         ELSE LAG (x) OVER (ORDER BY pid)
                      END
                         x,
                      CASE WHEN p.eid = c.eid THEN 'ematch' ELSE 'pmatch' END
                         ematch
                 FROM p_x_stg p, tab_c c
                WHERE p.eid = c.eid(+)
             ORDER BY pid, eid)
      WHERE x IS NOT NULL
   ORDER BY pid;
result is
1     e1     100     ematch
1     e2     100     pmatch
1     e3     300     ematch
2     e3     300     ematch
2     e4     300     pmatchI want below result
1    e1    100    ematch
1    e2    null    pmatch
1    e3    300    ematch
2    e3    300    ematch
2    e4    null    pmatchfor 1, e2 and 2, e4, instead of copying, just put null
Edited by: user650888 on Apr 6, 2012 12:29 PM

Hi,
user650888 wrote:
thanks, can this be combined into one query ?Do you mean without a sub-query?
Why? What's wrong with a sub-query?
If uisng a sub-query is the clearest and most efficient way to get the results you want, why wouldn't you want to use a sub-query?
Suppose there was a way, that involved some other technique. How would we know that you didn't object to that technique as well?
At any rate, I don't see how to do it without a sub-query. Analytic functions are computed after the WHERE clause is applied. If you want to use the results of an analytic function in a WHERE clause (as here, we want to use the results of the analytic COUNT function in a WHERE clause), then you have to compute the analytic function separately, in another (sub-) query.

Similar Messages

  • Analytical function question

    Hi,
    I'm looking for the best way to count the number of orders since a particular order that had a particular status. The ordernumbers are sequentially numbered, the key field is a sequence value and there is an orderdate field.
    I've tried the usual "x = select max xxx" and that works well for a small number of records, but not for updating 51M.
    Suggestions would be appreciated.
    Victor

    I solved this problem with an inner select with two first_value statements and an outer select with a >= between the two.

  • Question for analytic functions experts

    Hi,
    I have an ugly table containing an implicit master detail relation.
    The table can be ordered by sequence and then each detail is beneath it's master (in sequence).
    If it is a detail, the master column is NULL and vice versa.
    Sample:
    SEQUENCE MASTER DETAIL BOTH_PRIMARY_KEYS
    1____________A______________1
    2___________________A_______1
    3___________________B_______2
    4____________B______________2
    5___________________A_______3
    6___________________B_______4
    Task: Go into the table with the primary key of my detail, and search the primary key of it's master.
    I already have a solution how to get it, but I would like to know if there is an analytic statement,
    which is more elegant, instead of selfreferencing my table three times. Somebody used to analytic functions?
    Thanks,
    Dirk

    Hi,
    Do you mean like this?
    with data as (
    select 1 sequence, 'A' master, null detail, 1 both_primary_keys from dual union all
    select 2, null, 'A', 1 from dual union all
    select 3, null, 'B', 2 from dual union all
    select 4, 'B', null, 2 from dual union all
    select 5, null, 'A', 3 from dual union all
    select 6, null, 'B', 4 from dual )
    select (select max(both_primary_keys) keep (dense_rank last order by sequence)
            from data
            where sequence < detail_record.sequence and detail is null) master_primary_key
    from data detail_record
    where (both_primary_keys=3 /*lookup detail key 3 */  and master is null)

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

  • Replacing Oracle's FIRST_VALUE and LAST_VALUE analytical functions.

    Hi,
    I am using OBI 10.1.3.2.1 where, I guess, EVALUATE is not available. I would like to know alternatives, esp. to replace Oracle's FIRST_VALUE and LAST_VALUE analytical functions.
    I want to track some changes. For example, there are four methods of travel - Air, Train, Road and Sea. Would like to know traveler's first method of traveling and the last method of traveling in an year. If both of them match then a certain action is taken. If they do not match, then another action is taken.
    I tried as under.
    1. Get Sequence ID for each travel within an year per traveler as Sequence_Id.
    2. Get the Lowest Sequence ID (which should be 1) for travels within an year per traveler as Sequence_LId.
    3. Get the Highest Sequence ID (which could be 1 or greater than 1) for travels within an year per traveler as Sequence_HId.
    4. If Sequence ID = Lowest Sequence ID then display the method of travel as First Method of Travel.
    5. If Sequence ID = Highest Sequence ID then display the method of travel as Latest Method of Travel.
    6. If First Method of Travel = Latest Method of Travel then display Yes/No as Match.
    The issue is cells could be blank in First Method of Travel and Last Method of Travel unless the traveler traveled only once in an year.
    Using Oracle's FIRST_VALUE and LAST_VALUE analytical functions, I can get a result like
    Traveler | Card Issue Date | Journey Date | Method | First Method of Travel | Last Method of Travel | Match?
    ABC | 01/01/2000 | 04/04/2000 | Road | Road | Air | No
    ABC | 01/01/2000 | 15/12/2000 | Air | Road | Air | No
    XYZ | 01/01/2000 | 04/05/2000 | Train | Train | Train | Yes
    XYZ | 01/01/2000 | 04/11/2000 | Train | Train | Train | Yes
    Using OBI Answers, I am getting something like this.
    Traveler | Card Issue Date | Journey Date | Method | First Method of Travel | Last Method of Travel | Match?
    ABC | 01/01/2000 | 04/04/2000 | Road | Road | <BLANK> | No
    ABC | 01/01/2000 | 15/12/2000 | Air | <BLANK> | Air | No
    XYZ | 01/01/2000 | 04/05/2000 | Train | Train | <BLANK> | No
    XYZ | 01/01/2000 | 04/11/2000 | Train | <BLANK> | Train | No
    Above, for XYZ traveler the Match? clearly shows a wrong result (although somehow it's correct for traveler ABC).
    Would appreciate if someone can guide me how to resolve the issue.
    Many thanks,
    Manoj.
    Edited by: mandix on 27-Nov-2009 08:43
    Edited by: mandix on 27-Nov-2009 08:47

    Hi,
    Just to recap, in OBI 10.1.3.2.1, I am trying to find an alternative way to FIRST_VALUE and LAST_VALUE analytical functions used in Oracle. Somehow, I feel it's achievable. I would like to know answers to the following questions.
    1. Is there any way of referring to a cell value and displaying it in other cells for a reference value?
    For example, can I display the First Method of Travel for traveler 'ABC' and 'XYZ' for all the rows returned in the same column, respectively?
    2. I tried RMIN, RMAX functions in the RDP but it does not accept "BY" clause (for example, RMIN(Transaction_Id BY Traveler) to define Lowest Sequence Id per traveler). Am I doing something wrong here? Why can a formula with "BY" clause be defined in Answers but not the RPD? The idea is to use this in Answers. This is in relation to my first question.
    Could someone please let me know?
    I understand that this thread that I have posted is related to something that can be done outside OBI, but still would like to know.
    If anything is not clear please let me know.
    Thanks,
    Manoj.

  • Analytic Functions with GROUP-BY Clause?

    I'm just getting acquainted with analytical functions. I like them. I'm having a problem, though. I want to sum up the results, but either I'm running into a limitation or I'm writing the SQL wrong. Any hints for me?
    Hypothetical Table SALES consisting of a DAY_ID, PRODUCT_ID, PURCHASER_ID, PURCHASE_PRICE lists all the
    Hypothetical Business Question: Product prices can fluctuate over the course of a day. I want to know how much per day I would have made had I sold one each of all my products at their max price for that day. Silly question, I know, but it's the best I could come up with to show the problem.
    INSERT INTO SALES VALUES(1,1,1,1.0);
    INSERT INTO SALES VALUES(1,1,1,2.0);
    INSERT INTO SALES VALUES(1,2,1,3.0);
    INSERT INTO SALES VALUES(1,2,1,4.0);
    INSERT INTO SALES VALUES(2,1,1,5.0);
    INSERT INTO SALES VALUES(2,1,1,6.0);
    INSERT INTO SALES VALUES(2,2,1,7.0);
    INSERT INTO SALES VALUES(2,2,1,8.0);
    COMMIT;
    Day 1: Iif I had sold one product 1 at $2 and one product 2 at $4, I would have made 6$.
    Day 2: Iif I had sold one product 1 at $6 and one product 2 at $8, I would have made 14$.
    The desired result set is:
    DAY_ID                 MY_MEASURE
    1                        6
    1                       14The following SQL gets me tantalizingly close:
    SELECT DAY_ID,
      MAX(PURCHASE_PRICE)
      KEEP(DENSE_RANK FIRST ORDER BY PURCHASE_PRICE DESC)
      OVER(PARTITION BY DAY_ID, PRODUCT_ID) AS MY_MEASURE
      FROM SALES
    ORDER BY DAY_ID
    DAY_ID                 MY_MEASURE
    1                      2
    1                      2
    1                      4
    1                      4
    2                      6
    2                      6
    2                      8
    2                      8But as you can see, my result set is "longer" than I wanted it to be. I want a single row per DAY_ID. I understand what the analytical functions are doing here, and I acknowledge that I am "not doing it right." I just can't seem to figure out how to make it work.
    Trying to do a sum() of max() simply does not work, nor does any semblance of a group-by clause that I can come up with. Unfortunately, as soon as I add the windowing function, I am no longer allowed to use group-by expressions (I think).
    I am using a reporting tool, so unfortunately using things like inline views are not an option. I need to be able to define "MY_MEASURE" as something the query tool can apply the SUM() function to in its generated SQL.
    (Note: The actual problem is slightly less easy to conceptualize, but solving this conundrum will take me much closer to solving the other.)
    I humbly solicit your collective wisdom, oh forum.

    Thanks, SY. I went that way originally too. Unfortunately that's no different from what I could get without the RANK function.
    SELECT  DAY_ID,
            PRODUCT_ID,
            MAX(PURCHASE_PRICE) MAX_PRICE
      FROM  SALES
      GROUP BY DAY_ID,
               PRODUCT_ID
      ORDER BY DAY_ID,
               PRODUCT_ID
    DAY_ID                 PRODUCT_ID             MAX_PRICE             
    1                      1                      2                     
    1                      2                      4                     
    2                      1                      6                     
    2                      2                      8

  • Grouping error in Oracle's analytic function  PERCENTILE_CONT()

    Hi,
    I have a question regarding the usage of Oracle's analytic function PERCENTILE_CONT(). The underlying time data in the table is of hourly granularity and I want to fetch average, peak values for the day along with 80th percentile for that day. For the sake of clarification I am only posting relevant portion of the query.
    Any idea how to rewrite the query and achieve the same objective?
    SELECT   TRUNC (sdd.ts) AS ts,
             max(sdd.maxvalue) AS max_value, avg(sdd.avgvalue) AS avg_value,
             PERCENTILE_CONT(0.80) WITHIN GROUP (ORDER BY  sdd.avgvalue ASC) OVER (PARTITION BY pm.sysid,trunc(sdd.ts)) as Percentile_Cont_AVG
    FROM     XYZ
    WHERE
              XYZ
    GROUP BY  TRUNC (sdd.ts)  
    ORDER BY  TRUNC (sdd.ts)
    Oracle Error:
    ERROR at line 5:
    ORA-00979: not a GROUP BY expression

    You probably mixed up the aggregate and analytical versin of PERCENTILE_CONT.
    The below should work, but i dont know if it produces the desireed results.
    SELECT   TRUNC (sdd.ts) AS ts,
             max(sdd.maxvalue) AS max_value, avg(sdd.avgvalue) AS avg_value,
             PERCENTILE_CONT(0.80) WITHIN GROUP (ORDER BY  sdd.avgvalue ASC)  as Percentile_Cont_AVG
    FROM     XYZ
    sorry, what is this where clause for??
    WHERE
              XYZ
    GROUP BY  TRUNC (sdd.ts)  
    ORDER BY  TRUNC (sdd.ts) Edited by: chris227 on 26.03.2013 05:45

  • Understanding row_number() and using it in an analytic function

    Dear all;
    I have been playing around with row_number and trying to understand how to use it and yet I still cant figure it out...
    I have the following code below
    create table Employee(
        ID                 VARCHAR2(4 BYTE)         NOT NULL,
       First_Name         VARCHAR2(10 BYTE),
       Last_Name          VARCHAR2(10 BYTE),
        Start_Date         DATE,
        End_Date           DATE,
         Salary             Number(8,2),
       City               VARCHAR2(10 BYTE),
        Description        VARCHAR2(15 BYTE)
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary,  City,       Description)
                 values ('01','Jason',    'Martin',  to_date('19960725','YYYYMMDD'), to_date('20060725','YYYYMMDD'), 1234.56, 'Toronto',  'Programmer');
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary,  City,       Description)
                  values('02','Alison',   'Mathews', to_date('19760321','YYYYMMDD'), to_date('19860221','YYYYMMDD'), 6661.78, 'Vancouver','Tester')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary,  City,       Description)
                 values('03','James',    'Smith',   to_date('19781212','YYYYMMDD'), to_date('19900315','YYYYMMDD'), 6544.78, 'Vancouver','Tester')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary,  City,       Description)
                  values('04','Celia',    'Rice',    to_date('19821024','YYYYMMDD'), to_date('19990421','YYYYMMDD'), 2344.78, 'Vancouver','Manager')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary,  City,       Description)
                  values('05','Robert',   'Black',   to_date('19840115','YYYYMMDD'), to_date('19980808','YYYYMMDD'), 2334.78, 'Vancouver','Tester')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary, City,        Description)
                  values('06','Linda',    'Green',   to_date('19870730','YYYYMMDD'), to_date('19960104','YYYYMMDD'), 4322.78,'New York',  'Tester')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary, City,        Description)
                  values('07','David',    'Larry',   to_date('19901231','YYYYMMDD'), to_date('19980212','YYYYMMDD'), 7897.78,'New York',  'Manager')
    insert into Employee(ID,  First_Name, Last_Name, Start_Date,                     End_Date,                       Salary, City,        Description)
                   values('08','James',    'Cat',     to_date('19960917','YYYYMMDD'), to_date('20020415','YYYYMMDD'), 1232.78,'Vancouver', 'Tester')I did a simple select statement
    select * from Employee e
    and it returns this below
    ID   FIRST_NAME LAST_NAME  START_DAT END_DATE      SALARY CITY       DESCRIPTION
    01   Jason      Martin     25-JUL-96 25-JUL-06    1234.56 Toronto    Programmer
    02   Alison     Mathews    21-MAR-76 21-FEB-86    6661.78 Vancouver  Tester
    03   James      Smith      12-DEC-78 15-MAR-90    6544.78 Vancouver  Tester
    04   Celia      Rice       24-OCT-82 21-APR-99    2344.78 Vancouver  Manager
    05   Robert     Black      15-JAN-84 08-AUG-98    2334.78 Vancouver  Tester
    06   Linda      Green      30-JUL-87 04-JAN-96    4322.78 New York   Tester
    07   David      Larry      31-DEC-90 12-FEB-98    7897.78 New York   Manager
    08   James      Cat        17-SEP-96 15-APR-02    1232.78 Vancouver  TesterI wrote another select statement with row_number. see below
    SELECT first_name, last_name, salary, city, description, id,
       ROW_NUMBER() OVER(PARTITION BY description ORDER BY city desc) "Test#"
       FROM employee
       and I get this result
    First_name  last_name   Salary         City             Description         ID         Test#
    Celina          Rice         2344.78      Vancouver    Manager             04          1
    David          Larry         7897.78      New York    Manager             07          2
    Jason          Martin       1234.56      Toronto      Programmer        01          1
    Alison         Mathews    6661.78      Vancouver   Tester               02          1 
    James         Cat           1232.78      Vancouver    Tester              08          2
    Robert        Black         2334.78     Vancouver     Tester              05          3
    James        Smith         6544.78     Vancouver     Tester              03          4
    Linda         Green        4322.78      New York      Tester             06           5
    I understand the partition by which means basically for each associated group a unique number wiill be assigned for that row, so in this case since tester is one group, manager is another group, and programmer is another group then tester gets its own unique number for each row, manager as well and etc.What is throwing me off is the order by and how this numbering are assigned. why is
    1 assigned to Alison Mathews for the tester group and 2 assigned to James Cat and 3 assigned Robert Black
    I apologize if this is a stupid question, i have tried reading about it online and looking at the oracle documentation but that still dont fully understand why.

    user13328581 wrote:
    understanding row_number() and using it in an analytic functionROW_NUMBER () IS an analytic fucntion. Are you trying to use the results of ROW_NUMBER in another analytic function? If so, you need a sub-query. Analuytic functions can't be nested within other analytic functions.
    ...I have the following code below
    ... I did a simple select statementThanks for posting all that! It's really helpful.
    ... and I get this result
    First_name  last_name   Salary         City             Description         ID         Test#
    Celina          Rice         2344.78      Vancouver    Manager             04          1
    David          Larry         7897.78      New York    Manager             07          2
    Jason          Martin       1234.56      Toronto      Programmer        01          1
    Alison         Mathews    6661.78      Vancouver   Tester               02          1 
    James         Cat           1232.78      Vancouver    Tester              08          2
    Robert        Black         2334.78     Vancouver     Tester              05          3
    James        Smith         6544.78     Vancouver     Tester              03          4
    Linda         Green        4322.78      New York      Tester             06           5... What is throwing me off is the order by and how this numbering are assigned. why is
    1 assigned to Alison Mathews for the tester group and 2 assigned to James Cat and 3 assigned Robert Black That's determined by the analytic ORDER BY clause. Yiou said "ORDER BY city desc", so a row where city='Vancouver' will get a lower namber than one where city='New York', since 'Vancouver' comes after 'New York' in alphabetic order.
    If you have several rows that all have the same city, then you can be sure that ROW_NUMBER will assign them consecutive numbers, but it's arbitrary which one of them will be lowest and which highest. For example, you have 5 'Tester's: 4 from Vancouver and 1 from New York. There's no particular reason why the one with first_name='Alison' got assinge 1, and 'James' got #2. If you run the same query again, without changing the table at all, then 'Robert' might be #1. It's certain that the 4 Vancouver rows will be assigned numbers 1 through 4, but there's no way of telling which of those 4 rows will get which of those 4 numbers.
    Similar to a query's ORDER BY clause, the analytic ORDER BY clause can have two or more expressions. The N-th one will only be considered if there was a tie for all (N-1) earlier ones. For example "ORDER BY city DESC, last_name, first_name" would mena 'Vancouver' comes before 'New York', but, if multiple rows all have city='Vancouver', last_name would determine the order: 'Black' would get a lower number than 'Cat'. If you had multiple rows with city='Vancouver' and last_name='Black', then the order would be determined by first_name.

  • Analytic function should produce different results

    Hi All
    My question is derived by a usage of the analytic functions with "sliding window". Let's say you have a table as
    GROUP_ID SEQ VALUE
    1 1 1
    1 1 2
    2 2 3
    2 3 4
    Then the query
    select sum( value ) over ( partition by group_id order by group_id, seq ) from a_table
    should produce different values for different runs because rows 1,2 have the same value of SEQ. One run may produce 2 then 1 another one may produce 1 then 2.
    I need to prove it if the statement above is true. Oracle caches data so if run it several times you will see the same result.
    Thanks.

    Why are you using group_id twice, in partition and order by? And why would several "runs" on the same data provide different results?
    C.

  • Query in analytic function

    Hi,
    I am using below query
    select * from
    SELECT FLAG,S_DATE,ROW_NUMBER() OVER (PARTITION BY
    flag order by S_DATE,FLAG ) as d
    FROM table_name
    ORDER BY S_DATE
    which gives below output
    Flag     | S_DATE      | D
    Y     | 2/27/2012 5:33     |     1
    Y     | 2/27/2012 5:34     |     2
    Y     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:34     |     1
    N     | 2/27/2012 5:34     |     2
    N     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:35     |     4
    N     | 2/27/2012 5:35     |     5
    Y     |  2/27/2012 5:36     |     4
    Y     |  2/27/2012 5:36     |     5
    Y     |  2/27/2012 5:36     |     6
    But i want the output to be in below order there is change in last 3 rows
    Flag     | S_DATE      | D
    Y     | 2/27/2012 5:33     |     1
    Y     | 2/27/2012 5:34     |     2
    Y     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:34     |     1
    N     | 2/27/2012 5:34     |     2
    N     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:35     |     4
    N     | 2/27/2012 5:35     |     5
    Y     |  2/27/2012 5:36     |     1
    Y     |  2/27/2012 5:36     |     2
    Y     |  2/27/2012 5:36     |     3
    ihave used the analytic function.
    Edited by: user8858890 on Feb 27, 2012 2:00 AM

    Hi,
    user8858890 wrote:
    ... But i want the output to be in below order there is change in last 3 rows
    Flag     | S_DATE      | D
    Y     | 2/27/2012 5:33     |     1
    Y     | 2/27/2012 5:34     |     2
    Y     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:34     |     1
    N     | 2/27/2012 5:34     |     2
    N     | 2/27/2012 5:34     |     3
    N     | 2/27/2012 5:35     |     4
    N     | 2/27/2012 5:35     |     5
    Y     |  2/27/2012 5:36     |     1
    Y     |  2/27/2012 5:36     |     2
    Y     |  2/27/2012 5:36     |     3
    Why do you want the last 3 rows (which have flag = 'Y') to be numbered 1, 2, 3, when the first 3 rows (which also have flag = 'Y') already have numbers 1, 2 and 3? Do you want a separate #1 whenevever there is a group of consecutive rows (when ordered by s_date) that have the same flag? If so, then you have to identify the groups, like this:
    WITH     got_grp_id     AS
         SELECT     flag
         ,     s_date
         ,     ROWID               AS r_id
         ,     ROW_NUMBER () OVER ( ORDER BY      s_date
                                   ,                  ROWID
               - ROW_NUMBER () OVER ( PARTITION BY  flag
                                         ORDER BY          s_date
                             ,               ROWID
                           )    AS grp_id
         FROM    table_name
    SELECT       flag
    ,       s_date
    ,       ROW_NUMBER () OVER ( PARTITION BY  flag
                                 ,          grp_id
                          ORDER BY          s_date
                          ,               r_id
                        )      AS d
    FROM      got_grp_id
    ORDER BY  s_date
    ,            grp_id
    ,       d
    ;This assumes that each row can be uniquely idendified, so that the order is unambiguous. In your sample data, there are completely identical rows, so I used ROWID to uniquely identify the rows. Using ROWID assumes that table_name is a real table, not just a result set.
    I hope this answers your question.
    If not, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) for all the tables involved, and the results you want from that data.
    Explain, using specific examples, how you get those results from that data.
    Always say what version of Oracle you're using.

  • Using analytical functions

    I need to categorize the entries in col c1 as follows:
    1. if the entry in col c1 has only positive values in col c2, then that entry in col c1 gets a category of PRD.
    2. if the entry in col c1 has only negative values in col c2, then that entry in col c1 gets a category of RMT.
    3. if the entry in col c1 has both positive and negative values in col c2, then that entry in col c1 gets a category of INT.
    Here's the data table:
    CREATE TABLE K_TST
    C1 VARCHAR2(10),
    C2 NUMBER
    c1     c2
    a     1
    a     -1
    a     -3
    a     2
    a     -2
    b     1
    c     -1
    d     1
    d     2
    d     3
    So I use the following query:
    select a.c1,
         a.init_category,
         count(*) over (partition by a.c1) category_count,
         decode(count(*) over (partition by a.c1), 1, a.init_category, 'INT') final_category
    from
         select distinct
              c1,
              decode(instr(to_char(c2), '-'), 0, 'PRD', 'RMT') init_category
         from k_tst
    ) a
    The idea is that I assign only categories PRD and RMT in the sub-query and then use the analytical function to count if an entry in col c1 belongs to more than one category. If it belongs to more than one category in the subquery, then the category is reassigned to INT.
    No problem, the result is:
    C1     INIT_CATEGORY     CATEGORY_COUNT     FINAL_CATEGORY
    a     PRD          2          INT
    a     RMT          2          INT
    b     PRD          1          PRD
    c     RMT          1          RMT
    d     PRD          1          PRD
    The report that I want is without INIT_CATEGORY col and only distinct values, so I modify the query from above to this:
    select distinct
         a.c1,
    --     a.init_category,
         count(*) over (partition by a.c1) category_count,
         decode(count(*) over (partition by a.c1), 1, a.init_category, 'INT') final_category
    from
         select distinct
              c1,
              decode(instr(to_char(c2), '-'), 0, 'PRD', 'RMT') init_category
         from k_tst
    ) a
    The result is:
    C1     CATEGORY_COUNT     FINAL_CATEGORY
    a     5          INT
    b     1          PRD
    c     1          RMT
    d     3          INT
    Note the the CATEGORY_COUNT for 'a' changed to 5 and CATEGORY_COUNT for 'd' changed to 3. So 'd' is now categorized as INT instead of the desired category PRD (all entries in col c2 for 'd' are positive).
    Why did the results of CATEGORY_COUNT change by merely adding the 'distinct' to the outer query?
    Thanks for the time to answer this question.

    I need to categorize the entries in col c1 as follows:
    1. if the entry in col c1 has only positive values in col c2, then that entry in col c1 gets a category of PRD.
    2. if the entry in col c1 has only negative values in col c2, then that entry in col c1 gets a category of RMT.
    3. if the entry in col c1 has both positive and negative values in col c2, then that entry in col c1 gets a category of INT.
    Here's the data table:
    CREATE TABLE K_TST
    C1 VARCHAR2(10),
    C2 NUMBER
    c1     c2
    a     1
    a     -1
    a     -3
    a     2
    a     -2
    b     1
    c     -1
    d     1
    d     2
    d     3
    So I use the following query:
    select a.c1,
         a.init_category,
         count(*) over (partition by a.c1) category_count,
         decode(count(*) over (partition by a.c1), 1, a.init_category, 'INT') final_category
    from
         select distinct
              c1,
              decode(instr(to_char(c2), '-'), 0, 'PRD', 'RMT') init_category
         from k_tst
    ) a
    The idea is that I assign only categories PRD and RMT in the sub-query and then use the analytical function to count if an entry in col c1 belongs to more than one category. If it belongs to more than one category in the subquery, then the category is reassigned to INT.
    No problem, the result is:
    C1     INIT_CATEGORY     CATEGORY_COUNT     FINAL_CATEGORY
    a     PRD          2          INT
    a     RMT          2          INT
    b     PRD          1          PRD
    c     RMT          1          RMT
    d     PRD          1          PRD
    The report that I want is without INIT_CATEGORY col and only distinct values, so I modify the query from above to this:
    select distinct
         a.c1,
    --     a.init_category,
         count(*) over (partition by a.c1) category_count,
         decode(count(*) over (partition by a.c1), 1, a.init_category, 'INT') final_category
    from
         select distinct
              c1,
              decode(instr(to_char(c2), '-'), 0, 'PRD', 'RMT') init_category
         from k_tst
    ) a
    The result is:
    C1     CATEGORY_COUNT     FINAL_CATEGORY
    a     5          INT
    b     1          PRD
    c     1          RMT
    d     3          INT
    Note the the CATEGORY_COUNT for 'a' changed to 5 and CATEGORY_COUNT for 'd' changed to 3. So 'd' is now categorized as INT instead of the desired category PRD (all entries in col c2 for 'd' are positive).
    Why did the results of CATEGORY_COUNT change by merely adding the 'distinct' to the outer query?
    Thanks for the time to answer this question.

  • Using analytic function in a view

    Hello to all
    Sorry If I use this thread
    sql not merge using analytic functions
    for my question,
    From example you write and from Tom explain is not possible create a view on analytic function?
    Thanks and sorry again

    I think what you'll discover is that if you apply the function over the result set, the initial SQL might be quicker,
    for example, this is a test I did with a large dictionary view:
    select tp.Table_Name
          ,tp.Partition_Name
    from
          select tbl.Table_Name         as Table_Name
                ,tbl.Partition_Date     as dt
                ,row_number() over (partition by dtp.table_Name order by dtp.Partition_Name desc) rn
          from (
                select  /*+ all_rows */
                        dtp.Table_Name
                       ,dtp.Partition_name
                from    dba_tab_partitions  dtp
                where   dtp.Partition_Name  like 'Y____\_Q_\_M__\_D__' escape '\'
                and     dtp.Table_Owner     =  'APPS'
                and     dtp.Table_name      not like '%$%'
                and     dtp.Table_Name      like '%'
               ) tbl
        ) tp
    where tp.rn = 1
    select Table_Name
          ,Partition_Name
    from (
          select  /*+ all_rows */
                  dtp.Table_Name
                 ,row_number() over (partition by tbl.table_Name order by tbl.Partition_Name desc) rn
          from    dba_tab_partitions  dtp
          where   dtp.Partition_Name  like 'Y____\_Q_\_M__\_D__' escape '\'
          and     dtp.Table_Owner     =  'APPS'
          and     dtp.Table_name      not like '%$%'
          and     dtp.Table_Name      '%'
         ) tbl
    where rn = 1I found the former to be quicker.
    I think ask tom was saying a lot more, but included something similar,
    Edited by: bluefrog on Jun 10, 2010 12:48 PM

  • SD & FI BI functional Questions

    Hi Experts,
    I need to ask some questions to customer on SD & FI functional related questions for BI Analytical reports..
    Already cutomer implemented Data ware house Informatica with congnos reporting tool.
    right now they want to implement BI.
    please any one can share on what type functional questions could ask the customer.
    Advance Thanks,
    Bala.

    Hi,
    A few more pointers.
    Start with Reports. What the client is using. What he is expecting.
    If he got existing reports map the fields with Business Content BW Fields. Go to Business content and make a list of queries which are delivered from SAP. Explain them the KPI's. This should be good to start with. Also check the Tcodes they use.
    Look for DataSources that get data from theses Tcode's.
    Project Preparation (Initial stuff -- Do a conceptual review after this phase requirements gathering)
    Collect requirement thru interviews with Business teams /Core users / Information Leaders.
    Study & analyze KPI's (key figures) of Business process.
    Identify the measurement criteria's (Characteristics).
    Understand the Drill down requirements if any.
    Understand the Business process data flow if any.
    Identify the needs for data staging layers in BW – (i. e need for ODS if any)
    Understand the system landscape.
    Prepare Final Requirements Documents in the form of Functional Specifications containing:
    Report Owners, Data flow, KPI's, measurement criteria's, Report format along with drilldown requirements.
    Hope this helps.
    Thanks,
    JituK

  • I don't believe if analytic functions do it for me or not

    Hey everyone,
    I'm looking for a way handling this report for my own job.
    a table having the following attributes exists.
    Create table Test (
    Public_Date varchar2(10),
    City varchar2(10),
    count     number(3))
    Query with the following output readily could be produced using group by clause.
    Year Sum
    2005 23
    2006 36
    2007 15
    2008 10
    But the question is that How I can lead to the following output.
    (I want to merge some records into one record in the output, in this example
    sum of all years after 2005 is my interest not each year individually come before)
    Year(s) Sum
    2005 23
    2006 36
    2007,2008 25 /*(15+10)*/
    I think analytic functions may be useful in producing this output but I don't know how.
    Could everyone help me how to handle this?

    Hi,
    You can use a CASE (or DECODE) statement to map all the years after 2006 to some common value, like 9999, and GROUP BY that computed value.
    If you want the 9999 row to be labeled '2007, 2008', do a search for "string aggregate" for various techniques, or see Tom Kyte's excellent page on this subject:
    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
    I use STRAGG (near the top of the page).

  • Build interface using analytic functions twice

    Hi all, tell me please is it possible to build interface using analytic functions twice, like:
    select max(tt.val) from (
    select id, sum(val) val
    from (
    select 1 id, 10 val from dual union all
    select 2 id, 10 val from dual union all
    select 2 id, 30 val from dual union all
    select 2 id, 10 val from dual union all
    select 3 id, 20 val from dual) t
    group by id) tt
    thanks in advance

    HI,
    Just a question...
    You used only dual table. That correspond to the reality or is just as example?
    I mean, won't physical table be used?
    I believe you need that at target column, is that true?

Maybe you are looking for

  • Sync ipad2 with multiple iTunes libraries

    Hi I am trying to work out how to sync my ipad2 with two separate iTunes libraries (one for my music, one for my wifes). The libraries are on our windows xp pc.  I can't find any help on the Apple support website. Is this even possible? All help grat

  • WRT310N will not recognize my modem

    I have a WRT310N, the network is setup up, its on pppoe, but the internet will not connect when im connected to my router. My modem does work when directly connected to my computer.

  • Load Balancing Exchange 2010 with Citrix Netscaler

    Hi All, I have two exchange multirole server(cas/ht/mb) EXCH1 and EXCH2 both are configured in DAG (dag1.example.com) and also both are configured with CAS array (casarray.example.com) We have Cirtix Netscaller hardware load balancer. I have to confi

  • Xconnect problem. cant ping from CE to CE

    Hi Guys, I'm having issues with my xconnect tunnel. i couldn't ping from CE to CE. is theres something that i missed in my config? CE2#sh run int Gi0/0.1104 Building configuration... Current configuration : 201 bytes interface GigabitEthernet0/0.1104

  • Music and skipping problem

    So recently I was asked to make a flowing soundtrack. One entire continuous stream about 3 hours long. Upon exporting I have had two different problems. 1. When I export I get and L and an R. Obviously Left and Right. I can't place both on the comput