Connect_by_root in 9i

Hi,
I'm using Oracle 9i db and I'm wondering what would be the best (fast, simple..) way to get the
connect_by_root hierarchical function functionality from the 10g.
Tnx, Mario

Derive the path with SYS_CONNECT_BY_PATH and SUBSTR it for the first element, e.g.
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production
SQL> SELECT ename, path,
  2         SUBSTR (path, 2,
  3           INSTR (path, '/', 1, 2) - 2) root
  4  FROM  (SELECT LPAD (' ', (LEVEL - 1) * 2) || ename ename,
  5                SYS_CONNECT_BY_PATH (ename, '/') || '/' path
  6         FROM   emp e
  7         START WITH ename IN ('JONES', 'BLAKE', 'CLARK')
  8         CONNECT BY PRIOR e.empno = e.mgr);
ENAME                PATH                           ROOT
JONES                /JONES/                        JONES
  SCOTT              /JONES/SCOTT/                  JONES
    ADAMS            /JONES/SCOTT/ADAMS/            JONES
  FORD               /JONES/FORD/                   JONES
    SMITH            /JONES/FORD/SMITH/             JONES
BLAKE                /BLAKE/                        BLAKE
  ALLEN              /BLAKE/ALLEN/                  BLAKE
  WARD               /BLAKE/WARD/                   BLAKE
  MARTIN             /BLAKE/MARTIN/                 BLAKE
  TURNER             /BLAKE/TURNER/                 BLAKE
  JAMES              /BLAKE/JAMES/                  BLAKE
CLARK                /CLARK/                        CLARK
  MILLER             /CLARK/MILLER/                 CLARK
13 rows selected.
SQL>

Similar Messages

  • Heirarchical query...inside another to get connect_by_root

    Given the following table:
    CREATE TABLE TEST_HIERARCHY
    CREATE TABLE TEST_HIERARCHY
    UDL_GUID INTEGER,
    DESCRIPTION VARCHAR2(50),
    PARENT_UDL_GUID INTEGER,
    CONSTRAINT TEST_HIERARCHY_PK
    PRIMARY KEY
    (UDL_GUID)
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (1, 'Parent 1', NULL);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (2, 'Child 1', 1);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (3, 'Child 2', 2);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (4, 'Child 3', 2);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (5, 'Parent 2', NULL);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (6, 'Child 4', 5);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (7, 'child 5', 5);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (8, 'child 6', 7);
    Insert into TEST_HIERARCHY
    (UDL_GUID, DESCRIPTION, PARENT_UDL_GUID)
    Values
    (9, 'child 7', 7);
    COMMIT;
    And running the following SELECT:
    select level, description, udl_guid, parent_udl_guid
    from test_hierarchy
    start with parent_udl_guid in (
    select distinct
    connect_by_root udl_guid from test_hierarchy
    where udl_guid in( 8, 4)
    start with parent_udl_guid is null
    connect by prior udl_guid = parent_udl_guid
    connect by prior udl_guid = parent_udl_guid
    I get this error:
    ORA-00600: internal error code, arguments: [qctcte1], [0], [], [], [], [], [], []
    I'm guessing this isn't allowed or this is a bug?
    What we're trying to do is....users get a list of items to be 'assigned' to a vehicle for transport. If an item is part of a parent child relationship (ie- a crate containing boxes of other items) then we need to ask the user if they want to bring along everything that is linked or nothing at all (no in between, all or nothing). So what I'm trying to do is get a statement that allows you to specify the items that were selected, and pull a result set of the entire heirarchy (or heirarchies) that the selected items are part of.
    So the above inserts get you:
    Parent 1
    -- child 1
    -- -- child 2
    -- -- child 3
    parent 2
    -- child 4
    -- child 5
    -- -- child 6
    -- -- child 7
    So if a user were to select child 5 and 7, they would get the whole parent 2 hierarchy. If they select 7 and 2, they would get both parent 1 and 2's hierarchy. (I know the above columns listed are not guids, I had to dumb this down for myself so I could follow who was chasing who. Integers are so much easier)
    Searching metalink didn't get me any obvious results. I can run either query by itself and get results. I can even run a subquery for the main hierarchical query which is a normal SELECT. Oracle falls apart when trying to process them both.
    Anybody see a different way to do this? This is 10gR2 running on RHEL4. Thanks.

    ora-600's should always be checked against metalink
    https://metalink.oracle.com/metalink/plsql/f?p=130:14:3038746456038321058::::p14_database_id,p14_docid,p14_show_header,p14_show_help,p14_black_frame,p14_font:NOT,248095.1,1,0,1,helvetica
    also, it works fine for me
    SQL> select * from v$version;
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - Prod
    PL/SQL Release 10.1.0.2.0 - Production
    CORE    10.1.0.2.0      Production
    TNS for 32-bit Windows: Version 10.1.0.2.0 - Production
    NLSRTL Version 10.1.0.2.0 - Production
    5 rows selected.
    SQL> select level, description, udl_guid, parent_udl_guid
      2  from test_hierarchy
      3  start with parent_udl_guid in (
      4  select distinct
      5  connect_by_root udl_guid from test_hierarchy
      6  where udl_guid in( 8, 4)
      7  start with parent_udl_guid is null
      8  connect by prior udl_guid = parent_udl_guid
      9  )
    10  connect by prior udl_guid = parent_udl_guid
    11  /
         LEVEL DESCRIPTION                                          UDL_GUID PARENT_UDL_GUID
             1 Child 1                                                     2               1
             2 Child 2                                                     3               2
             2 Child 3                                                     4               2
             1 Child 4                                                     6               5
             1 child 5                                                     7               5
             2 child 6                                                     8               7
             2 child 7                                                     9               7
    7 rows selected.

  • Connect_By_Root: Difference between Oracle 10.2.0.1.0 and 11.1.0.6.0

    Hello,
    we use the connect_by_root function. Now we would like transfer our application to 11g 64Bit
    Under the following Database 10g it works fine
    Oracle Database 10g Release 10.2.0.1.0 - Production
    PL/SQL Release 10.2.0.1.0 - Production
    CORE     10.2.0.1.0     Production
    TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
    NLSRTL Version 10.2.0.1.0 - Production
    drop table hier;
    create table hier
    parent varchar2(30),
    child varchar2(30)
    insert into hier values(null,'Asien');
    insert into hier values(null,'Australien');
    insert into hier values(null,'Europa');
    insert into hier values('Asien','China');
    insert into hier values('Asien','Japan');
    insert into hier values('Europa','Deutschland');
    set linesize 5000;
    column child format a80
    select
    connect_by_root child || ' #Pipapo#' as Child1
    ,sys_connect_by_path(child,'/') as Path
    from
    hier
    start with parent is null
    connect by prior child = parent;
    Output:
    CHILD1 PATH
    Asien #Pipapo# /Asien
    Asien #Pipapo# /Asien/China
    Asien #Pipapo# /Asien/Japan
    Australien #Pipapo# /Australien
    Europa #Pipapo# /Europa
    Europa #Pipapo# /Europa/Deutschland
    Under the following Database 11g we get the following error:
    Oracle Database 11g Release 11.1.0.6.0 - 64bit Production
    PL/SQL Release 11.1.0.6.0 - Production
    CORE     11.1.0.6.0     Production
    TNS for 64-bit Windows: Version 11.1.0.6.0 - Production
    NLSRTL Version 11.1.0.6.0 - Production
    FEHLER in Zeile 1:
    ORA-00932: Inkonsistente Datentypen: NUMBER erwartet, - erhalten
    The result from conect_by_root cannot concat with ' #Pipapo#'
    We need this funktionality. What can we do. Its a bug in 11g ?
    best regards
    Horst Hanke

    It does not work under 10.2.0.3.0 too !!!
    Oracle Database 10g Release 10.2.0.3.0 - Production
    PL/SQL Release 10.2.0.3.0 - Production
    CORE     10.2.0.3.0     Production
    TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
    NLSRTL Version 10.2.0.3.0 - Production
    best reagrds
    Horst Hanke
    Please Help !!!

  • Group by at diferente levels of a three (connect_by_root like in 9i)

    Hi,
    I'm working with version 9ir2 (9.2.0.4 - 9.2.0.6) and need to do something like connect_by_root, but at diferent leveles.
    The table acting as a tree is for the areas/departaments of the company
    Level Use
    1st Company itself
    2nd Administration, Production
    3rd Directions
    4th Departaments
    5th Sub-departments
    I need to group diferent reports at the 3rd and fourth levels, the 3rd level must sum/count 3rd itself and fourt to n. The same is for 4th level.
    I could do it for 3rd level, but don't imagine how to do for 4th level at the same time on the same query.
    Any help is welcome.
    Thanks in advance

    It should be possible to modify the following macro to achieve what you are after:
    ' Macro created 29/09/99 by Doug Robbins to replace endnotes with textnotes at end of document
    ' to replace the endnote reference in the body of the document with a superscript number.
    Dim aendnote As Endnote
    For Each aendnote In ActiveDocument.Endnotes
    ActiveDocument.Range.InsertAfter vbCr & aendnote.Index & vbTab & aendnote.Range
    aendnote.Reference.InsertBefore "a" & aendnote.Index & "a"
    Next aendnote
    For Each aendnote In ActiveDocument.Endnotes
    aendnote.Reference.Delete
    Next aendnote
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find.Replacement.Font
    .Superscript = True
    End With
    With Selection.Find
    .Text = "(a)([0-9]{1,})(a)"
    .Replacement.Text = "\2"
    .Forward = True
    .Wrap = wdFindContinue
    .Format = True
    .MatchWildcards = True
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
    If you can send me a copy of the document, or put a copy of it in a folder on your OneDrive that you set to be shared and post a link to it back here, I will have a go at making the necessary modifications.
    Doug Robbins - Word MVP dkr[atsymbol]mvps[dot]org

  • Creating N Copies of a Row using "CONNECT BY CONNECT_BY_ROOT"

    This isn't a question. I just wanted to share a technique I stumbled upon while
    jamming with Vadim Tropashko on his blog recently.
    Occasionally the ability to create n copies of a row is required.
    For example, given a table with this data
    create table t ( key integer, string varchar2(10), qty integer );
    insert into t values ( 1, 'a', 2 );
    insert into t values ( 2, 'b', 3 );
    commit;
           KEY STRING            QTY
             1 a                   2
             2 b                   3
    sometimes we need queries that produce 2 copies of row 1 and 3 copies of row 2,
    like this.
           KEY STRING            QTY
             1 a                   2
             1 a                   2
             2 b                   3
             2 b                   3
             2 b                   3
    A query like the following would be ideal, but unfortunately Oracle doesn't
    like the existence of a CONNECT BY loop.
    select key, string, qty, level from t
    CONNECT BY STRING = PRIOR STRING AND LEVEL <= QTY
    order by 1, 4 ;
    select key, string, qty, level from t
    ERROR at line 1:
    ORA-01436: CONNECT BY loop in user data
    Without the CONNECT BY loop we won't get the right number of rows however.
    select key, string, qty, level, sys_connect_by_path( string, '/' ) path
    from t
    CONNECT BY LEVEL <= QTY
    order by 1, 4 ;
           KEY STRING            QTY      LEVEL PATH
             1 a                   2          1 /a
             1 a                   2          2 /b/a
             1 a                   2          2 /a/a
             2 b                   3          1 /b
             2 b                   3          2 /b/b
             2 b                   3          2 /a/b
             2 b                   3          3 /b/a/b
             2 b                   3          3 /b/b/b
             2 b                   3          3 /a/a/b
             2 b                   3          3 /a/b/b
    The final solution employs CONNECT_BY_ROOT to yield the desired result
    without triggering an error.
    select key, string, qty, level, sys_connect_by_path( string, '/' ) path
    from t
    CONNECT BY CONNECT_BY_ROOT KEY = KEY AND LEVEL <= QTY
    order by 1, 4 ;
           KEY STRING            QTY      LEVEL PATH
             1 a                   2          1 /a
             1 a                   2          2 /a/a
             2 b                   3          1 /b
             2 b                   3          2 /b/b
             2 b                   3          3 /b/b/b
    Here's an example of this "CONNECT BY CONNECT_BY_ROOT" technique in action.
    It splits a comma separated value string into one row per value.
    delete from t;
    insert into t values( 1, 'a,bb,ccc'  , null );
    insert into t values( 2, 'dddd,eeeee', null );
    commit;
    select
      string ,
      level as position ,
      regexp_substr( string, '[^,]+', 1, level ) as val
    from
      t
    connect by
      connect_by_root key = key and
      regexp_substr( string, '[^,]+', 1, level ) is not null
    order by
      1, 2
    STRING       POSITION VAL
    a,bb,ccc            1 a
    a,bb,ccc            2 bb
    a,bb,ccc            3 ccc
    dddd,eeeee          1 dddd
    dddd,eeeee          2 eeeee--
    Joe Fuda
    SQL Snippets

    Nice approach.
    BTW it is just another way of workaround for CONNECT BY LOOP error.
    You can also do this like:
    SQL> select key, string, qty, level
      2    from t
      3  CONNECT BY STRING = PRIOR STRING
      4         AND LEVEL <= QTY
      5         and prior dbms_random.value is not null
      6   order by 1, 4;
                                        KEY STRING                                         QTY      LEVEL
                                          1 a                                                2          1
                                          1 a                                                2          2
                                          2 b                                                3          1
                                          2 b                                                3          2
                                          2 b                                                3          3
    S

  • How can I count patterns of multiple rows in a table

    I just can't wrap my head around a query I need to identify the unique set of patterns with a table...by patterns I mean the following...
    This is medical procedural data, wherein the first procedure code is followed by 0 or more procedures in a sequence for each case. I need to find out how many of each sequence of procedures exist in the table from all the cases...
    row_id caseid proc_code sequence
    1 1 A 1
    2 1 B 2
    3 2 C 1
    4 3 A 1
    5 3 B 2
    So in this example data set I would like an output like this (something similar that would produce the number of times A followed B...and so on)
    row_id proc_set count(*)
    1 A-B 2
    2 C 1
    If someone could at least point me in a direction, I'd appreciate it...thanks ron.

    Interesting variation, Solomon.Yes, but gives different results if there are more than two linked procedures:
    SQL> with t as (
      2             select 1 case_id,'A' proc_code,1 seq from dual union all
      3             select 1,'B',2 from dual union all
      4             select 1,'C',3 from dual union all
      5             select 2,'C',1 from dual union all
      6             select 3,'A',1 from dual union all
      7             select 3,'B',2 from dual
      8            )
      9  select  proc_set,
    10          count(*) cnt
    11    from  (
    12           select  case level
    13                     when 1 then proc_code
    14                     else connect_by_root(proc_code) || '-' || proc_cod
    15                   end proc_set
    16             from  t
    17             where connect_by_isleaf = 1
    18             start with seq = 1
    19             connect by case_id = prior case_id
    20                    and seq     = prior seq + 1
    21          )
    22    group by proc_set
    23  /
    PROC_SET                    CNT
    A-B                           1
    C                             1
    A-C                           1While we get
    SQL> with t as (
      2  select 1 row_id, 1 caseid, 'A' proc_code, 1 sequence from dual union
      3  select 2, 1, 'B', 2 from dual union
      4  select 4, 2, 'C', 1 from dual union
      5  select 3, 1, 'C', 3 from dual union
      6  select 5, 3, 'A', 1 from dual union
      7  select 6, 3, 'B', 2 from dual)
      8  select row_number() over (order by proc_set) row_id,  proc_set, count(0) from (
      9  select ltrim(sys_connect_by_path(proc_code,'-'),'-') proc_set
    10    from t
    11  where connect_by_isleaf=1
    12  connect by prior sequence+1 = sequence and prior caseid=caseid
    13  start with sequence=1)
    14  group by proc_set;
        ROW_ID PROC_SET               COUNT(0)
             1 A-B                           1
             2 A-B-C                         1
             3 C                             1Max
    [My Italian Oracle blog|http://oracleitalia.wordpress.com/2009/12/29/estrarre-i-dati-in-formato-xml-da-sql/]

  • How can I convert this small pl/sql block in a single query?

    Hello,
    I need to have a single SQL query which gives the same output as the following piece of code, which uses a cursor to iterate on the rows in order to get the informations I need:
    declare
    cursor c(p varchar2) is
    select context_id, id, parent_id
    from CONTEXT_CONTEXT
    start with parent_id is null
    and context_id = p
    connect by prior id = parent_id
    and context_id = p;
    begin
    for r in (select context_id from ALL_CONTEXTS where context_type in ('MYTYPE'))
    loop
    for j in c(r.context_id)
    loop
    -- I want to obtain the values of the following colums from a query:
    dbms_output.put_line(j.context_id || ' ' || j.id || ' ' || j.parent_id);
    end loop;
    end loop;
    end;
    Additional informations:
    CONTEXT_CONTEXT.context_id references ALL_CONTEXTS.id
    CONTEXT_CONTEXT.id references ALL_CONTEXTS.id as well
    CONTEXT_CONTEXT.parent_id references ALL_CONTEXTS.id as well
    id is primary key of ALL_CONTEXTS
    (context_id, id) is primary key of CONTEXT_CONTEXT
    */

    user10047839 wrote:
    Unfortunately, the CONNECT_BY_ROOT is not supported by my version of the DB 9i.
    SELECT  context_id,
            SUBSTR(
                   SYS_CONNECT_BY_PATH(context_id,'/'),
                   2,
                   INSTR(
                         SYS_CONNECT_BY_PATH(context_id,'/') || '/',
                         1,
                         2
                        ) - 2
                  ) AS parent_context_id
      FROM  CONTEXT_CONTEXT
      START WITH parent_id IS NULL
        AND context_id IN (
                           SELECT  context_id
                             FROM  all_contexts
                             WHERE context_type IN ('MYTYPE')
      CONNECT BY PRIOR ID = parent_id
             AND context_id = PRIOR context_id;SY.

  • Finding the number of connected components in a graph

    I don't know haow many people have seen this problem posted on c.d.o.m, but here is the essence
    given an equivalence relation, e.g.
    x y
    1 1
    2 2
    2 1
    1 2
    3 3
    find the number of equivalence classes. In this example equivalence classes are {1,2} and {3}.

    The idea: Label all the graph nodes with distinct primes. Find all simple paths in the graph weighted with product of nodes. Find the skyline of all maximal products. Count them.
    Implementation (swithced to boolean vectors instead of primes)
    create table input as (
    select 1 x, 2 y from dual
    union
    select 2, 3 from dual
    union
    select 2, 4 from dual
    union
    select 6, 7 from dual
    union
    select 8, 9 from dual);
    with TC as (
    select connect_by_root(x) x, y
    from (
    select x,y from input
    union
    select y,x from input
    ) connect by nocycle x = prior y
    ), weightedNodes as (
    select node, power(2,rownum-1) code
    from (select x node from input
    union select y node from input )
    select count(distinct code) from (
    select x,y,sum(code) code from (
    select distinct pre.x, pre.y mid, post.y from TC pre, TC post
    where pre.y=post.x
    ), weightedNodes
    where node = mid
    group by x,y
    drop table input;

  • Loading data from a table to another

    This question is continuation of my earlier thread
    Re: query help
    The last thread was answered by experts and was closed. But I have another problem, I'll put the whole scenario here:
    I have a table with data as
    id          status_code  emp_id
    1           a                10
    2           b                10
    3           a                20
    4           c                30
    5           k                10
    6           k                10
    7           a                10
    8           a                20
    9           z                20
    10           k                30
    11           k                30
    12           m                20
    13           k                10
    14           k                30and scripts are:
    CREATE TABLE TEST
    (id NUMBER,
    status_code VARCHAR2(5),
    emp_id NUMBER
    INSERT INTO test VALUES (1,'a',10);
    INSERT INTO test VALUES (2,'b',10);
    INSERT INTO test VALUES (3,'a',20);
    INSERT INTO test VALUES (4,'c',30);
    INSERT INTO test VALUES (5,'k',10);
    INSERT INTO test VALUES (6,'k',10);
    INSERT INTO test VALUES (7,'a',10);
    INSERT INTO test VALUES (8,'a',20);
    INSERT INTO test VALUES (9,'z',20);
    INSERT INTO test VALUES (10,'k',30);
    INSERT INTO test VALUES (11,'k',30);
    INSERT INTO test VALUES (12,'m',20);
    INSERT INTO test VALUES (13,'k',10);
    INSERT INTO test VALUES (14,'k',30);Here's the query that experts gave me in last thread, to fetch desired records:
    The requirement was to fetch records of those emp ids where a given emp_id consectively gets same status code.
    Each emp id gets a status code and at times it gets same status code as its previous status code. And I am interested in such scenarios.
    For example,
    emp_id=20 gets status_code=a in id=3 and its next status_code is also =a at id=8,
    emp_id=10 gets status_code=k in id=5 and gets same status_code again in id=6,
    emp_id=30 gets status_code=k in id=10 and gets same status code in id=11 and id=14.
    And the answer was:
    select *
    from
    select
      id,
      status_code,
      emp_id,
      lag(status_code) over (partition by emp_id order by id asc) as last_status,
      lead(status_code) over (partition by emp_id order by id asc) as next_status 
    from test
    where status_code = last_status
    or status_code = next_status
      / But now the new issue is that the records of the table TEST are to be loaded into another table TEST_REVISED . For each ID of table TEST, there will be one or more records in table TEST_REVISED.
    ALTER TABLE TEST ADD (CONSTRAINT id_pk  PRIMARY KEY(id));
    CREATE TABLE TEST_REVISED
    (TR_ID NUMBER PRIMARY KEY,
    ID     NUMBER REFERENCES TEST(ID),
    NEW_STATUS_CODE VARCHAR2(5)
    );This is what I want to see in table TEST_REVISED
    TR_ID,     ID,        NEW_STATUS_CODE
    100,        1,          'test-code'
    200,        2,'         'test-code'
    300,        3,         'test-code'
    400,        4,          'test-code'
    500,        5,          'test-code'
    600,        5,           'test-code'--notice here: EMP_ID=10 had same status consecutively in table TEST, so when that record is loaded to TEST_REVISED, ID=5 is used                instead of  id=6
    700,        7,          'test-code'
    800,        3,           'test-code'--notice here: EMP_ID=20 had same status  consecutively in table TEST, so when that record is loaded to TEST_REVISED, ID=3 is used  instead of id=8
    900,        9,           'test-code'
    1000,      10,         'test-code'
    1100,      10,           'test-code'--notice here: EMP_D=30 had same status  consecutively in table TEST, so when that record is loaded to TEST_REVISED, ID=10 is used  instead of id=11
    1200,      12,             'test-code'
    1300,      13,             'test-code'
    1400,      10,             'test-code'--notice here: EMP_ID=30 had same status  consecutively in table TEST, so when that record is loaded to TEST_REVISED, ID=10 is used  instead of id=14 or id=11Ignore the value of the column NEW_STATUS_CODE here.
    How can I load data in table TEST_REVISED from table TEST keeping in view the requirement I mentioned? Table TEST has around 1 million records.
    Once this achieved, I want to delete records from table TEST with following ids :
    ID=6,8,11,14.
    Thanks a lot!
    Edited by: user5406804 on Dec 5, 2010 5:49 PM
    Edited by: user5406804 on Dec 5, 2010 5:50 PM

    OK, i still don't see how this is all supposed to fit together.
    You haven't said it, but i'm assuming when you have a series like
    id   emp status_code
    1    30   k
    2    30   k
    3    10   a
    4    30  k
    5    30  kYou actually want the output to be
    id   emp status_code   new_id
    1    30   k                   1
    2    30   k                   1
    3    10   a                   3
    4    30  k                    4
    5    30  k                    4Which presents a bit of a problem using simply analytic functions.
    So here's the modified query that picks up just the rows you want 'changed'.
    TUBBY_TUBBZ?
    select
      id,
      emp_id,
      status_code,
      connect_by_root(id) as new_id
    from
      select
        id,
        emp_id,
        status_code,
        lag(status_code)  over (partition by emp_id, status_code order by id asc) as last_status,
        row_number()      over (partition by emp_id, status_code order by id asc) as rn
      from
        select
          id,
          emp_id,
          status_code,
          lead(status_code) over (partition by emp_id order by id asc) as next_code,
          lag(status_code) over (partition by emp_id order by id asc) as last_code,
          row_number() over (partition by emp_id order by id asc) as rn
        from test
      where status_code in (last_code, next_code)
    start with last_status is null
    connect by prior emp_id = emp_id
    and prior status_code = status_code
    and prior rn = rn - 1
         ID     EMP_ID STATU     NEW_ID
          5        10 k           5
          6        10 k           5
          3        20 a           3
          8        20 a           3
         10        30 k          10
         11        30 k          10
         14        30 k          10
    7 rows selected.
    TUBBY_TUBBZ?You say you have a lot of rows in the TEST table, and i'm hoping and praying this is a one time requirement and not an on-going process that needs to occur so your best bet (performance wise) would probably be to use the above query to create a temporary table.
    Use that temporary table to control the rest of the process (inserting into TEMP_REVISED and deleting from TEST).
    That's the best i can think of based on what i believe your requirement is ... and i honestly don't think that's going to perform overly well (the connect by functionality specifically).

  • Searching Criteria to find out the friends of friend

    Senior DBA'S
    i need to make database where i need to search the person from the current user. Current user can have many friends in his friend list but whom current user searching may be he is not a friend of current user and find out how current user known to that person. Like a friend's Chain.
    Suppose that i m Aman finding out "San". my friends are Abhi, johan, satish etc,
    further abhi's friend is "San" and
    Satish is friend of Mohan, Mohan further friend of Sanju and Sanju will be friend of "San"
    so "Aman" known to "San" by two ways one way by Abhi and 2nd way by Satish. Like link will be
    Aman -> Abhi -> San
    Aman -> Satish -> Mohan -> Sanju -> San
    which way i am asking that is used by linkedin (www.linkedin.com)
    So, Please tell me what best searching criteria will be used to achieve the target with performance because Records can be in billions.

    should be like that
    create table PALS (
    pal_id number primary key ,
    Name varchar2(100));
    drop table FRIENDS;
    create table FRIENDS(
    pal_id number ,
    friend_id number ,
    primary key(pal_id , friend_id),
    foreign key (pal_id) references PALS(pal_id),
    foreign key (friend_id) references PALS(pal_id)
    insert into pals values (1,'A');
    insert into pals values (2,'B');
    insert into pals values (3,'C');
    insert into pals values (4,'D');
    insert into pals values (5,'E');
    insert into pals values (6,'F');
    insert into pals values (7,'G');
    insert into friends values (1,2);
    insert into friends values (1,3);
    insert into friends values (2,5);
    insert into friends values (5,7);
    insert into friends values (3,4);
    insert into friends values (4,6);
    insert into friends values (6,7);
    commit;
    -- find leads to G
    with PF as (
    select p.pal_id, p.name, f.friend_id, pf.name friend
    from pals p
    join friends f on p.pal_id=f.pal_id
    join pals pf on pf.pal_id=f.friend_id)
    select level, pf.name, pf.friend
    from PF
    connect by prior pal_id = friend_id start with friend='G';
         LEVEL NAME       FRIEND  
             1 E          G         
             2 B          E         
             1 F          G         
             2 D          F         
             3 C          D          then you have to unwrap it in application.
    May be it is possible in SQL also.
    Edited by: Mark Malakanov (user11181920) on Jan 10, 2013 10:56 AM
    I've found how to do it
    with PF as (
    select p.pal_id, p.name, f.friend_id, pf.name friend
    from pals p
    join friends f on p.pal_id=f.pal_id
    join pals pf on pf.pal_id=f.friend_id),
    W as (
    select level, pf.name, pf.friend,
    CONNECT_BY_ROOT name R,
    SYS_CONNECT_BY_PATH(friend,' -> ') P,
    CONNECT_BY_ISLEAF IsLeaf
    from PF
    connect by pal_id = prior friend_id start with name='A'
    select R || P P from W where IsLeaf=1 and friend='G';
    P                                                                             
    A -> B -> E -> G                                                                
    A -> C -> D -> F -> G  Edited by: Mark Malakanov (user11181920) on Jan 10, 2013 11:28 AM
    Edited by: Mark Malakanov (user11181920) on Jan 10, 2013 11:33 AM
    So, Please tell me what best searching criteria will be used to achieve the target with performance because Records can be in billions.create index PALS_NAME on PALS(NAME);
    or use PAL_ID in
    connect by pal_id = prior friend_id start with PAL_ID=1
    Edited by: Mark Malakanov (user11181920) on Jan 10, 2013 11:42 AM
    Edited by: Mark Malakanov (user11181920) on Jan 10, 2013 11:44 AM

  • Help needed in building query

    Tab1
    Parent       Child       sa l
    P1     A1       4000
    A1     A       1000
    A1     B       4000
    A     X       1000
    A     Y         2000
    B     X1        1000           
    B     X2       3000I need to build a query that will retrieve the value for each child as the sum of the salaries of all its child in a single query.
    That is
    For Sal P1 = Sal A1 + all child of A1 and its child
         For A1 = Sal A1 + all child of A1 and its child ( A+B+X+Y+X1+X2)
    Like it should sho all the records with the count .. please help

    This is not so simple since it is not really clear in your data set whether the sal belongs to the parent or to the child. I assume it's the salary of the child, in which case the salary of P1 is missing. The best option is to fix the data model and have two tables: one containing the element and sal, and another table containing just the relationships. To fix this issue I introduced a dummy record for P1 and salary 0.
    SQL> with t2 as
      2  ( select connect_by_root(child) cbr
      3         , sal
      4      from (select * from t union all select null,'P1',0 from dual)
      5   connect by parent = prior child
      6  )
      7  select cbr child
      8       , sum(sal)
      9    from t2
    10   group by cbr
    11  /
    CHILD    SUM(SAL)
    X1           1000
    A1          16000
    X2           3000
    P1          16000
    Y            2000
    X            1000
    A            4000
    B            8000
    8 rows selected.Regards,
    Rob.

  • Creating View for a table with parent child relation in table

    I need help creating a view. It is on a base table which is a metadata table.It is usinf parent child relationship. There are four types of objects, Job, Workflow, Dataflow and ABAP dataflow. Job would be the root parent everytime. I have saved all the jobs
    of the project in another table TABLE_JOB with column name JOB_NAME. Query should iteratively start from the job and search all the child nodes and then display all child with the job name. Attached are the images of base table data and expected view data
    and also the excel sheet with data.Picture 1 is the sample data in base table. Picture 2 is data in the view.
    Base Table
    PARENT_OBJ
    PAREBT_OBJ_TYPE
    DESCEN_OBJ
    DESCEN_OBJ_TYPE
    JOB_A
    JOB
    WF_1
    WORKFLOW
    JOB_A
    JOB
    DF_1
    DATAFLOW
    WF_1
    WORKFLOW
    DF_2
    DATAFLOW
    DF_1
    DATAFLOW
    ADF_1
    ADF
    JOB_B
    JOB
    WF_2
    WORKFLOW
    JOB_B
    JOB
    WF_3
    WORKFLOW
    WF_2
    WORKFLOW
    DF_3
    DATAFLOW
    WF_3
    WORKFLOW
    DF_4
    DATAFLOW
    DF_4
    DATAFLOW
    ADF_2
    ADF
    View
    Job_Name
    Flow_Name
    Flow_Type
    Job_A
    WF_1
    WORKFLOW
    Job_A
    DF_1
    DATAFLOW
    Job_A
    DF_2
    DATAFLOW
    Job_A
    ADF_1
    ADF
    Job_B
    WF_2
    WORKFLOW
    Job_B
    WF_3
    WORKFLOW
    Job_B
    DF_3
    DATAFLOW
    Job_B
    DF_4
    DATAFLOW
    Job_B
    ADF_2
    ADF
    I implemented the same in oracle using CONNECT_BY_ROOT and START WITH.
    Regards,
    Megha

    I think what you need is recursive CTE
    Consider your table below
    create table basetable
    (PARENT_OBJ varchar(10),
    PAREBT_OBJ_TYPE varchar(10),
    DESCEN_OBJ varchar(10),DESCEN_OBJ_TYPE varchar(10))
    INSERT basetable(PARENT_OBJ,PAREBT_OBJ_TYPE,DESCEN_OBJ,DESCEN_OBJ_TYPE)
    VALUES('JOB_A','JOB','WF_1','WORKFLOW'),
    ('JOB_A','JOB','DF_1','DATAFLOW'),
    ('WF_1','WORKFLOW','DF_2','DATAFLOW'),
    ('DF_1','DATAFLOW','ADF_1','ADF'),
    ('JOB_B','JOB','WF_2','WORKFLOW'),
    ('JOB_B','JOB','WF_3','WORKFLOW'),
    ('WF_2','WORKFLOW','DF_3','DATAFLOW'),
    ('WF_3','WORKFLOW','DF_4','DATAFLOW'),
    ('DF_4','DATAFLOW','ADF_2','ADF')
    ie first create a UDF like below to get hierarchy recursively
    CREATE FUNCTION GetHierarchy
    @Object varchar(10)
    RETURNS @RESULTS table
    PARENT_OBJ varchar(10),
    DESCEN_OBJ varchar(10),
    DESCEN_OBJ_TYPE varchar(10)
    AS
    BEGIN
    ;With CTE
    AS
    SELECT PARENT_OBJ,DESCEN_OBJ,DESCEN_OBJ_TYPE
    FROM basetable
    WHERE PARENT_OBJ = @Object
    UNION ALL
    SELECT b.PARENT_OBJ,b.DESCEN_OBJ,b.DESCEN_OBJ_TYPE
    FROM CTE c
    JOIN basetable b
    ON b.PARENT_OBJ = c.DESCEN_OBJ
    INSERT @RESULTS
    SELECT @Object,DESCEN_OBJ,DESCEN_OBJ_TYPE
    FROM CTE
    OPTION (MAXRECURSION 0)
    RETURN
    END
    Then you can invoke it as below
    SELECT * FROM dbo.GetHierarchy('JOB_A')
    Now you need to use this for every parent obj (start obj) in view 
    for that create view as below
    CREATE VIEW vw_Table
    AS
    SELECT f.*
    FROM (SELECT DISTINCT PARENT_OBJ FROM basetable r
    WHERE NOT EXISTS (SELECT 1
    FROM basetable WHERE DESCEN_OBJ = r.PARENT_OBJ)
    )b
    CROSS APPLY dbo.GetHierarchy(b.PARENT_OBJ) f
    GO
    This will make sure it will give full hieraracy for each start object
    Now just call view as below and see the output
    SELECT * FROM vw_table
    Output
    PARENT_OBJ DESCEN_OBJ DESCEN_OBJ_TYPE
    JOB_A WF_1 WORKFLOW
    JOB_A DF_1 DATAFLOW
    JOB_A ADF_1 ADF
    JOB_A DF_2 DATAFLOW
    JOB_B WF_2 WORKFLOW
    JOB_B WF_3 WORKFLOW
    JOB_B DF_4 DATAFLOW
    JOB_B ADF_2 ADF
    JOB_B DF_3 DATAFLOW
    Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs

  • Handling hierarchy in oracle sql query

    I have two tables:
    The first contains COMPANY_ID and CATEGORY_ID
    The second contains CATEGORY_ID and PARENT_CATEGORY_ID
    I need to return a list containing COMPANY_ID and CATEGORY_ID. The entries, however, must come not only from the first table, but also include all the descendants listed in the second table.
    So for example (and please read the example carefully) - let’s say in the first table I have one row:
    COMPANY_ID | CATEGORY_ID
    1000 | 1
    In the second table, I have three rows:
    CATEGORY_ID | PARENT_CATEGORY_ID
    1 | null
    2 | 1
    3 | 2
    4 | null
    I want to have the following rows as a result:
    COMPANY_ID | CATEGORY_ID
    1000 | 1
    1000 | 2
    1000 | 3
    How can I do this in oracle 10 in a single SQL statement ?

    Hi,
    Welcome to the forum!
    Whenver you have a question, post your sample data in a form that people can use.
    CREATE TABLE and INSERT statements are great:
    CREATE TABLE  first
    (       company_id     NUMBER (4)
    ,     category_id     NUMBER (4)
    INSERT INTO first (company_id, category_id) VALUES (1000,   1);CREATE TABLE AS is good, too:
    CREATE TABLE  second
    AS
    SELECT     1 AS category_id, NULL AS parent_category_id     FROM dual     UNION ALL
    SELECT     2,               1                          FROM dual     UNION ALL
    SELECT     3,               2                          FROM dual     UNION ALL
    SELECT     4,               NULL                    FROM dual;Without that, people can't test their ideas, and are often unsure about your data.
    You should also say what version of Oracle you're using. That's especially important with CONNECT BY queries. Every version since Oracle 7 has had significant improvements in how to do CONNECT BY queries. The query below works in Oracle 10 (and up).
    For hierarchies and trees, use CONNECT BY
    When you have to join tables and use CONNECT BY, it's usually more efficient to do one in a sub-query, and the other in another query.
    In the example below, we're doing the CONNECT BY in sub-query cbq, and the join in the main query.
    WITH     cbq     AS
         SELECT     category_id
         ,     CONNECT_BY_ROOT category_id     AS root_category_id
         FROM     second
         START WITH     parent_category_id     IS NULL
               AND     category_id          IN ( SELECT  category_id          -- Maybe; see note below
                                             FROM    first
         CONNECT BY     parent_category_id     = PRIOR category_id
    SELECT  first.company_id
    ,     cbq.category_id
    FROM     first
    JOIN     cbq     ON     first.category_id     = cbq.root_category_id
    ;The 2nd condition in the START WITH clause won't change the results any; any rows that are excluded by that condition would also be excluded by the join condition. There can be a big differenece in performance, however. Try the query both ways, and use the 2nd condition if it helps.
    Edited by: Frank Kulash on Feb 3, 2010 3:46 PM

  • Value of the start in the Select with in a Hierarchical Query

    Exist any way for put in the select the value of the start with in a Hierarchical Query?
    An example:
    I'll need sth like
    CTH@> select n code, level, np code_parent, 1 code_first_parent
    2 from demo
    3 start with n=1
    4 connect by np = prior n
    5 ;
    CODE LEVEL CODE_PARENT CODE_FIRST_PARENT
    1 1 1
    2 2 1 1
    3 3 2 1
    4 4 3 1
    5 5 4 1
    6 6 5 1
    7 7 6 1
    8 8 7 1
    9 9 8 1
    10 10 9 1
    -- Naturally it couldn´t be a constant value
    The query
    select n,d, level nivel
    , np, prior n
    from demo
    start with n=1
    connect by np = prior n
    --Table and inserts
    create table demo
    ( n number,
    d varchar2(5),
    np number);
    insert into demo values (1,'A', null);
    insert into demo values (2,'B',1);
    insert into demo values (3,'C',2);
    insert into demo values (4,'D',3);
    insert into demo values (5,'E',4);
    insert into demo values (6,'F',5);
    insert into demo values (7,'G',6);
    insert into demo values (8,'H',7);
    insert into demo values (9,'I',8);
    insert into demo values (10,'J',9);
    insert into demo values (11,'K', null);
    insert into demo values (12,'L',11);
    insert into demo values (13,'M',12);
    insert into demo values (14,'N',13);
    insert into demo values (15,'O',14);
    insert into demo values (16,'P',15);
    Message was edited by:
    cth

    On 10g
    connect_by_root(n)Best regards
    Maxim

  • SQL recursion problem in custom groups table

    hi all,
    Consider the following seemingly simple table structure ( with sample rows ) :
    PERMISSION_ID P_ID DESCRIPTION DESIGNATION
    ============= ==== =========== =======
    1776 Null Z-ENGINEERING 88888
    1860 Null Z-LABORATORY 88888
    1909 Null Z-RESEARCH 88888
    1902 Null Z-PLANT 88888
    1905 Null Z-SOFTWARE DESIGN 88888
    1903 Null Z-BLANKET 88888
    1904 Null Z-OFFICE 88888
    40000 1909 James Gosling 67890
    40001 1909 Edgar Codd 21135
    40002 1904 Alan Turing 85542
    40003 1909 Z-SOFTWARE DESIGN 88888
    40004 1905 Dennis Ritchie 12111
    40005 1909 Z-OFFICE 88888
    40006 1776 Brian Kernighan 84251
    40007 1904 Z-ENGINEERING 88888
    Explanation of table structure :
    (1) All rows with P_ID = {Null} are the root groups, and they all have a uniform DESIGNATION of 88888.
    (2) All rows that starts with 40000 are memberships; under these memberships scheme, a root group can become a member of another root group, cascaded, which means that root groups can be members of another root group or they can be members of multiple root groups ( and cascaded even ), as long as the cascade do not end up in a circular reference, or an endless cycle. The idea here is so that the memberships for both groups and human members can be chained.
    (3) Both root groups and human memberships are stored in the same table above, using rules (1) & (2) as the logic.
    (4) No additional table may be added to this table in order to implement rules (1), (2), & (3); columns may be added, though.
    (5) Use only plain SQL statements ( SELECT, CONNECT BY, PRIOR, NOCYCLES, etc ... ); PL/SQL, functions, and procedures are strongly discouraged.
    Desired output of the query is as follows :
    The SELECT query should return a list of all human members which belongs to a specific root group. Using the example table above, the initial query should have the following intended result set:
    (start with p_id = 1909) -- 1909 is root group Z-RESEARCH
    PERMISSION MEMBERS
    ========== =======
    40000 James Gosling
    40001 Edgar Codd
    40003 Z-SOFTWARE DESIGN
    40005 Z-OFFICE
    However, Z-SOFTWARE DESIGN has it's own member , Dennis Ritchie, so the updated result set should be :
    PERMISSION MEMBERS
    ========== =======
    40000 James Gosling
    40001 Edgar Codd
    40004 Dennis Ritche
    40005 Z-OFFICE
    Same is true for Z-OFFICE, but it's member is another root group, Z-ENGINEERING, whose member is Brian Kernighan, thus the final result set list would be as follows, which is the final intended list :
    PERMISSION MEMBERS
    ========== =======
    40000 James Gosling
    40001 Edgar Codd
    40004 Dennis Ritche
    40002 Alan Turing
    40006 Brian Kernighan
    The problem now would be, how to generate the final intended list using the table scheme illustrated above, with no additional tables, but possible additional columns, using Oracle's SELECT ... START WITH ... CONNECT BY PRIOR ?
    Any theoretical advice is greatly appreciated; even our consulting firm cannot solve this problem. Coming here to the Oracle Forums itself is a last resort. Perhaps someone here can take a gander at this seemingly simple problem. Fact is, solving this problem has lots of applications, one of which is the ability to mimic Outlook's nested distribution groups list.
    Thank you so much for your time.

    Ok, first time back at a database, here my 2 cent.
    I use the with-clause to simulate your sample-data, i have also added the master-reference-column i suggested. Just restrict the result to the group you want to. (i only put the id's in the query)
    WITH DATA AS (SELECT 1776 PERMISSION_ID, TO_NUMBER(NULL) P_ID, TO_NUMBER(NULL) MASTER_PERMISSION_ID, 'Z-ENGINEERING' DESCRIPTION,  88888 DESIGNATION FROM DUAL
                  UNION ALL
                  SELECT 1860, Null, Null, 'Z-LABORATORY', 88888 FROM DUAL
                  UNION ALL
                  SELECT 1909, Null, Null, 'Z-RESEARCH', 88888 FROM DUAL
                  UNION ALL
                  SELECT 1902, Null, Null, 'Z-PLANT' ,88888 FROM DUAL
                  UNION ALL
                  SELECT 1905, Null, Null, 'Z-SOFTWARE DESIGN', 88888 FROM DUAL
                  UNION ALL
                  SELECT 1903, Null, Null, 'Z-BLANKET', 88888 FROM DUAL
                  UNION ALL
                  SELECT 1904, Null, Null, 'Z-OFFICE', 88888 FROM DUAL
                  UNION ALL
                  SELECT 40000, 1909, Null, 'James Gosling', 67890 FROM DUAL
                  UNION ALL
                  SELECT 40001, 1909, Null, 'Edgar Codd', 21135  FROM DUAL
                  UNION ALL
                  SELECT 40002, 1904, Null, 'Alan Turing', 85542 FROM DUAL
                  UNION ALL
                  SELECT 40003, 1909, 1905, 'Z-SOFTWARE DESIGN', 88888 FROM DUAL
                  UNION ALL
                  SELECT 40004, 1905, Null, 'Dennis Ritchie', 12111 FROM DUAL
                  UNION ALL
                  SELECT 40005, 1909, 1904, 'Z-OFFICE', 88888 FROM DUAL
                  UNION ALL
                  SELECT 40006, 1776, Null, 'Brian Kernighan', 84251  FROM DUAL
                  UNION ALL
                  SELECT 40007, 1904, 1776, 'Z-ENGINEERING', 88888  FROM DUAL
    SELECT GROUP_REFERENCE,
           THE_USERS.PERMISSION_ID,
           USER_NAME,
           FROM_GROUP
      FROM (SELECT PERMISSION_ID,
                   DESCRIPTION FROM_GROUP,
                   CONNECT_BY_ROOT(PERMISSION_ID) GROUP_REFERENCE
              FROM (SELECT PERMISSION_ID, TO_NUMBER(NULL) P_MASTER, DESCRIPTION
                      FROM DATA
                     WHERE DESIGNATION=88888
                       AND P_ID IS NULL
                    UNION ALL
                    SELECT MASTER_PERMISSION_ID PERMISSION_ID,  P_ID P_MASTER, DESCRIPTION
                      FROM DATA
                     WHERE DESIGNATION=88888
                       AND P_ID IS NOT NULL       
            CONNECT BY PRIOR PERMISSION_ID=P_MASTER
            START WITH P_MASTER IS NULL
           ) THE_GROUPS,
           (SELECT P_ID PERMISSION_REFERENCE,
                   PERMISSION_ID,
                   DESCRIPTION USER_NAME
              FROM DATA
             WHERE MASTER_PERMISSION_ID IS NULL
               AND P_ID IS NOT NULL
           ) THE_USERS
    WHERE THE_GROUPS.PERMISSION_ID=THE_USERS.PERMISSION_REFERENCE

Maybe you are looking for

  • Not able to view data from more than one data package in PSA

    Hi Friends, Desparetly trying to view data in PSA. Problem : If i mark more than one datapackage this error raises: You must only select one data packet when entering data record numbers Message no. RSAODS127 And there is no change to reset data reco

  • Can't save layered .psd files in Photoshop CS3

    Hello, I noticed yesterday that I can no longer save layered .psd files to any folder. What does get saved is only a generic file symbol. I'm using a Dell 8200 computer, 1GB of RAM, IntelPentium4 processer, Windows XP Professional,and a Canon MP780 m

  • O.T. Are You Interested In Photo Masking/Compositing Software For Windows ?

    'Recomposit is a photo masking and compositing tool which precisely isolates image object from its background and merges it with others. The advanced masking methods: Bluescreen also called chroma key technology and inside/Outside edge will keep any

  • How do I disable an app's recent documents?

    When I secondary click an app in my Dock, it brings up a menu with a list of recently opened documents. How do I disable this so it doesn't display these?

  • Column Type Conversion Script

    Hi All, I would like to be able to perform a Column Datatype conversion on a database. I want to find all tables for a schema that has a CHAR type column and then convert it into VARCHAR2 of the same length and MODIFY existing data with a TRIM functi