Complex connect by prior query

I need SQL(for hierarchical tree) for a function which accepts node as input parameter and returns ref cursor.
Following is a sample tree:
1
--2.1
----3.1
------4.1
--------5.1
----------6.1
----------6.2
----3.2
------4.2
--------5.2
--2.2
----3.2
------4.2
--------5.2
----3.3
----3.4
------4.1
--------5.1
----------6.1
----------6.2
1 is at the root level and 2.1 & 2.2 are immediate children and so on.
The output tree should be all related parents and children of the passed node.
e.g:
If the input is 4.1, the output tree will be:
1
--2.1
----3.1
------4.1
--------5.1
----------6.1
----------6.2
--2.2
----3.4
------4.1
--------5.1
----------6.1
----------6.2
If the input is 4.2, the output tree will be:
1
--2.1
----3.2
------4.2
--------5.2
--2.2
----3.2
------4.2
--------5.2
The complex part, I guess, is to remove unwanted(not related) branches from the tree.
Following is the representation of the table RELATIONSHIP
ID     PARENT     CHILD
1-------1-------2.1
2-------1-------2.2
3-------2.1-----3.1
4-------2.1-----3.2
5-------2.2-----3.2
6-------2.2-----3.3
7-------2.2-----3.4
8-------3.1-----4.1
9-------3.2-----4.2
10------3.4-----4.1
11------4.1-----5.1
12------4.2-----5.2
13------5.1-----6.1
14------5.1-----6.2
Pls. help me out to form this CONNECT BY PRIOR query.
Thanks in advance.

make sure you include 2 things in your queries.
# the row number
# the level
for traversing up the tree set
level = 0 - level and
row_number = 0 - row_number.
you than can then do an order by row_number if you union the two queries
for example:
============
select tbl.child,
tbl.parent,
level lvl,
rownum rn
from some_table tbl
start with tbl.parent = 4.1
connect by prior tbl.child = tbl.parent
union
select tbl.child,
tbl.parent,
0 - level lvl,
0 - rownum rn
from some_table tbl
start with tbl.child = 4.1
connect by prior tbl.parent = tbl.child
order by rn asc

Similar Messages

  • Connect by prior query

    Issue with the below query. The query is not getting filtered for the condition hier_typ_c in('BS') with the connect by prior
    query. query is fetching all the hier_type_c in the table like 'BS', 'CO', 'EC' etc....
    Just wondering how do i restrict the query just to fetch the type_c ='BS' alone? why is it giving all the records??
    Select 
            Level                 as  LEVEL_CODE,
            h.HIER_PRNT_NODE_I    as  PARENT,
            h.HIER_CHLD_NODE_I    as  CHILD,
            h.HIER_CHLD_NODE_X || ' (' || h.HIER_CHLD_NODE_I || ')'   as  ALIAS
            From        (Select  Distinct HIER_CHLD_NODE_I, HIER_PRNT_NODE_I,
                                HIER_CHLD_NODE_X from .HIER_DIMN
                         where hier_typ_c in('BS') and CURR_VER_C = 'Y') h
                         Start with  h.HIER_PRNT_NODE_I = 'ROOT'
            Connect by prior
                   h.HIER_CHLD_NODE_I = h.HIER_PRNT_NODE_I
    Order by    LEVEL_CODE, parent, child

    Hi
    It loks like you're doing it right.
    By basing the CONNECT BY query on a sub-query that has this WHERE clasue:
    where hier_typ_c in('BS') and CURR_VER_C = 'Y') hyou should exclude not only nodes whose hier_typ_c is not 'BS', but also their descendants.
    Post some sample data (CREATE TABLE and INSERT statements) and the results you want from that data.
    Are you sure the query you posted is what you're actually running?
    I would expect the sub-query FROM clause to cause an error because of the '.'.
    from .HIER_DIMNEdited by: Frank Kulash on Sep 29, 2009 11:16 AM

  • Strange Behaviour of Connect By Prior query

    Has anybody faced a problem like your query returns alternative record like suppose you have 10 records in a table and your connect by prior query gives you 1st, 3rd, 5th and so on. My query was working fine few days back but suddenly its giving me different result. I don't know whether there was some settings changed by someone or not.

    Can't guess anything from here. You need to post the query, sample data and the result.

  • Need help: CONNECT by PRIOR query in ora10g

    Hi All,
    Recently we have migrated the DB from 9i to 10g.
    we used to have many rule based queries in 9i
    and all are changed based on 10g.
    All the queries that have CONNECT BY PRIOR
    conditions seems to behave in wrong manner.
    ( same query in 9i,fetches less number of records where as 10g there were many
    rows displayed eventhough it was not selected in where clause.- as per business logic )
    After changing the below parameter setting , the problem was solved.
    can you tell wts the below setting would do? by doing so , ur again making 10g
    to behave like 9i so that full benefit of 10g is not used ?
    Alter session set “_optimizer_connect_by_cost_based”=false

    Hi, try this:
    WITH t AS (
    SELECT 100 AS node_id, cast(NULL AS NUMBER) AS parent_node_id FROM dual UNION ALL
    SELECT 101 AS node_id, 100 AS parent_node_id FROM dual UNION ALL
    SELECT 102 AS node_id, 100 AS parent_node_id FROM dual UNION ALL
    SELECT 1021 AS node_id, 102 AS parent_node_id FROM dual UNION ALL
    SELECT 1022 AS node_id, 102 AS parent_node_id FROM dual UNION ALL
    SELECT 10221 AS node_id, 1022 AS parent_node_id FROM dual UNION ALL
    SELECT 10222 AS node_id, 1022 AS parent_node_id FROM dual
    SELECT DISTINCT CONNECT_BY_ROOT parent_node_id AS ID, node_id AS id1
    FROM t
    CONNECT BY t.node_id = PRIOR parent_node_id
    START WITH parent_node_id = 1022
    ORDER BY 1, 2;

  • I want to help  connect by prior query

    table structure
    node_id parent_node_id
    =======================
    100
    101 100
    102 100
    1021 102
    1022 102
    10221 1022
    10222 1022
    above example tree like-
    100
    101
    102
    1021
         1022
         10221
         10222
    i want to output like(if input 1022)
    id id1
    1022 100
    1022 102
    1022 1022
    1022 10221
    1022 10222
    create table node_temp(node_id number,parent_node_id number)
    insert into node_temp(node_id) values(100);
    insert into node_temp(node_id,parent_node_id) values(101,100);
    insert into node_temp(node_id,parent_node_id) values(102,100);
    insert into node_temp(node_id,parent_node_id) values(1021,102);
    insert into node_temp(node_id,parent_node_id) values(1022,102);
    insert into node_temp(node_id,parent_node_id) values(10221,1022);
    insert into node_temp(node_id,parent_node_id) values(10222,1022);
    Edited by: 855516 on Feb 1, 2013 1:46 PM

    Hi, try this:
    WITH t AS (
    SELECT 100 AS node_id, cast(NULL AS NUMBER) AS parent_node_id FROM dual UNION ALL
    SELECT 101 AS node_id, 100 AS parent_node_id FROM dual UNION ALL
    SELECT 102 AS node_id, 100 AS parent_node_id FROM dual UNION ALL
    SELECT 1021 AS node_id, 102 AS parent_node_id FROM dual UNION ALL
    SELECT 1022 AS node_id, 102 AS parent_node_id FROM dual UNION ALL
    SELECT 10221 AS node_id, 1022 AS parent_node_id FROM dual UNION ALL
    SELECT 10222 AS node_id, 1022 AS parent_node_id FROM dual
    SELECT DISTINCT CONNECT_BY_ROOT parent_node_id AS ID, node_id AS id1
    FROM t
    CONNECT BY t.node_id = PRIOR parent_node_id
    START WITH parent_node_id = 1022
    ORDER BY 1, 2;

  • How to use simple SQL instead of Connect By Prior

    Currently, I am using "connect by prior" query in the application, but for reason I don�t want to use this connect by query so can any one please tell how does I get the same result by using SQL, I tried this by using procedure but unable to get the same result, specially LEVEL of the tree.
    So please tell, how would I get the correct data.
    Thanks in advance,
    AMIT.

    Hi,
    Whenever you have a question, it helps to post:
    (1) The version of Oracle (and any other relevant software) you're using
    (2) A little sample data (just enough to show what the problem is) from all the relevant tables
    (3) The results you want from that data
    (4) Your best attempt so far (formatted) I don't believe the unformated code you posted is what you're really running, since it has a syntax error ("... WHERE START WITH ..."). Please post code that really works with the sample data you posrted.
    (5) The full error message (if any), including line number
    Executable SQL statements (like "CREATE TABLE AS ..." or "INSERT ..." statements) are best for (2).
    If you can present your problem using commonly available tables (for example, scott.emp, which contains a hierarchy), then you can omit (2).
    Formatted tabular output is okay for (3). Type these 6 characters
    {code}
    (small letters only, inside curly brackets) before and after the tabular text, to preserve spacing.
    As Alex said, why don't you want to use CONNECT BY?
    Are you getting the correct results now, but just looking for a different way of getting them?
    Depending on your exact requirements, you could write a PLSQL function that mimics LEVEL. Don't expect it to be fast.
    Nested Sets is a completely different way of modeling trees.
    Some things are much easier with Nested Sets than they are using the Adjacency Model (the parent-child model that uses CONNECT BY).
    But some things are much harder with Nested Sets, and LEVEL is one of them.

  • Help with 'connect by prior' statement

    I've got a quoting report that is sporadically ordering incorrectly and I've traced the source down to a 'connect by prior' statement. Can I get an explanation of what the statement is doing so I can figure out how to change it to get the desired results?
    select rownum config_rownum, quote_line_id,related_quote_line_id rlid, level
    from aso_line_relationships
    where relationship_type_code = 'CONFIG'
    connect by prior related_quote_line_id = quote_line_idsample output for the line_ids for one quote:
    CONFIG_ROWNUM     QUOTE_LINE_ID     RLID     LEVEL
    1          7438          7439     2
    2          7440          7441     2
    3          7430          7431     2
    4          7432          7433     2
    5          7432          7434     2
    6          7432          7435     2
    7          7436          7437     2
    8          7442          7443     2
    9          7442          7444     2
    10          7442          7445     2
    11          7442          7446     2
    12          7442          7447     2
    13          7442          7448     2
    14          7442          7449     2
    15          7450          7451     2
    16          7452          7453     2
    17          7452          7454     2
    18          7452          7455     2
    19          7456          7457     2
    20          7456          7458     2
    21          7456          7459     2
    22          7460          7461     2
    23          7460          7462     2
    24          7463          7464     2
    25          7430          7431     1
    26          7432          7433     1
    27          7432          7434     1
    28          7432          7435     1
    29          7436          7437     1
    30          7438          7439     1
    31          7440          7441     1
    32          7442          7443     1
    33          7442          7444     1
    34          7442          7445     1
    35          7442          7446     1
    36          7442          7447     1
    37          7442          7448     1
    38          7442          7449     1
    39          7450          7451     1
    40          7452          7453     1
    41          7452          7454     1
    42          7452          7455     1
    43          7456          7457     1
    44          7456          7458     1
    45          7456          7459     1
    46          7460          7461     1
    47          7460          7462     1
    48          7463          7464     1 The correct ordering can be seen by running this statement:
    select rownum config_rownum, quote_line_id,related_quote_line_id rlid
    from aso_line_relationships
    where relationship_type_code = 'CONFIG' and quote_line_id between 7430 and 7464
    CONFIG_ROWNUM     QUOTE_LINE_ID     RLID
    1          7430          7431
    2          7432          7433
    3          7432          7434
    4          7432          7435
    5          7436          7437
    6          7438          7439
    7          7440          7441
    8          7442          7443
    9          7442          7444
    10          7442          7445
    11          7442          7446
    12          7442          7447
    13          7442          7448
    14          7442          7449
    15          7450          7451
    16          7452          7453
    17          7452          7454
    18          7452          7455
    19          7456          7457
    20          7456          7458
    21          7456          7459
    22          7460          7461
    23          7460          7462
    24          7463          7464I tried to substitute the simple query above for the 'connect by prior' query in the report but failed because something in the report is expecting input from the 'connect by prior' statement. So eliminating the statement is not a choice.

    "connect by prior " is for for hierarchical queries which is for data has parent-children relationship, and ususlly its' result is used to populate tree-like data result. and order by is NOT recommend since it will destroy the hierarchical order.
    you could use "order by sibiling" if you would like to order inside the same level of data

  • Variable being lost after CONNECT BY...PRIOR query

    Im having an issue with the following code (snippet posted):
    SELECT ewpm_project_id INTO pro_id FROM ewpm_work_package WHERE
    ewpm_work_package_id = wp_id;
    --can return pro_id here
    SELECT ewpm_work_package_prefix, LEVEL INTO parent_prefix,
    parent_level
    FROM ewpm_work_package
    WHERE ewpm_project_id = temp_pro_id
    AND ewpm_work_package_id = wp_id
    START WITH ewpm_work_package_id = pack_id
    CONNECT BY PRIOR ewpm_work_package_id = ewpm_work_package_parent_id;
    RETURN pro_id;
    The pro_id value is correctly set during the first select statement, I
    can return the pro_id in the commented position. However, I can not
    return the value after the second select statement. All I am getting
    back is a null value. If I remove the START WITH.. CONNECT BY
    clauses in the second query, the pro_id value is returned correcly.
    Has anyone experienced this before, or know what could be causing it?

    However, I can not
    return the value after the second select statement. All I am getting
    back is a null value. If I remove the START WITH.. CONNECT BY
    clauses in the second query, the pro_id value is returned correcly.How do you use this function ? If you use it in SQL query then any
    SQL statement raising NO_DATA_FOUND exception leads to NULL returning
    as a result (like the subquery in a selection list which returns no one row):
    SQL> create function get_number
      2  return number
      3  is
      4   ret_val number;
      5  begin
      6  
      7   select 1 into ret_val from dual;
      8   return ret_val;
      9  end;
    10  /
    Function created.
    SQL> select get_number from dual;
    GET_NUMBER
             1
    SQL> create or replace function get_number
      2  return number
      3  is
      4   ret_val number;
      5   p number;
      6  begin
      7  
      8   select 1 into ret_val from dual;
      9 
    10   --This statement raises NO_DATA_FOUND
    11   select 1 into p from dual where rownum = 0;
    12 
    13   return ret_val;
    14  end;
    15  /
    Function created.
    SQL> select get_number from dual;
    GET_NUMBER
    ----------Check does
    SELECT ewpm_work_package_prefix, LEVEL
    FROM ewpm_work_package
    WHERE ewpm_project_id = temp_pro_id
    AND ewpm_work_package_id = wp_id
    START WITH ewpm_work_package_id = pack_id
    CONNECT BY PRIOR ewpm_work_package_id = ewpm_work_package_parent_id
    query return anything ?
    Rgds.

  • Query tuning for query using connect by prior

    I have written following query to fetch the data. The query is written in this format because there are multiple rows, which make one recrd and we need to bring that record into one row.
    For one CAT(commented here), this query takes around 4 minutes and fetches 6900 records but when it runs for 3 CAT, it takes 17 mins.
    I want to tune this as this has to run for 350 CAT values.
    It is doing FTS on the main table. I tried to use different hints like PARALLEL, APPEND (in insert) but nothing worked.
    The cost of the query is 51.
    Any help/suggestions will be appreciated.
    SELECT DISTINCT MIN(SEQ) SEQ,
    PT, APP, IT, LR, QT,CD, M_A_FLAG,
    STRAGG(REM) REM, -- aggregates the data from different columns to one which is parent
    CAT
    FROM (WITH R AS (SELECT CAT, SEQ, PT, M_A_FLAG, IT, LR,QT,CD, REM, APP
    FROM table1
    WHERE REC = '36' AND M_A_FLAG = '1'
    --AND CAT = '11113')
    SELECT CAT, SEQ,
    CONNECT_BY_ROOT PT AS PT,
    CONNECT_BY_ROOT APP AS APPL,
    M_A_FLAG,
    CONNECT_BY_ROOT IT AS IT,
    CONNECT_BY_ROOT LR AS LR,
    CONNECT_BY_ROOT QT AS QT,
    CONNECT_BY_ROOT CD AS CD,
    REM
    FROM R A
    START WITH PT IS NOT NULL
    CONNECT BY PRIOR SEQ + 1 = SEQ
    AND PRIOR CAT = CAT
    AND PT IS NULL)
    GROUP BY PT, APP, IT,LR, QT, CD, M_A_FLAG, CAT
    ORDER BY SEQ;
    Thanks.
    Edited by: user2544469 on Feb 11, 2011 1:12 AM

    The following threads detail the approach and information required.
    Please gather relevant info and post back.
    How to post a SQL tuning request - HOW TO: Post a SQL statement tuning request - template posting
    When your query takes too long - When your query takes too long ...

  • CONNECT BY PRIOR and performance of Query Plan

    Anyone,
    I have an SQL Statement that is performing rather slow and I am trying to figure out if I could optimize it. Here is the SQL:
       SELECT/*+ index(MAXIMO.EQNDX99) */
            maximo.equipment.eqnum, maximo.equipment.parent, LEVEL
       FROM maximo.equipment@maxi_dblink
       WHERE parent = :b1 CONNECT BY PRIOR eqnum = parent
       ORDER BY eqnum, LEVELAfter some research in this board I followed some advice found to create an index on the table for both the eqnum, parent and the parent, eqnum. EQNDX99 and EQNDX999 respectivley.
    Now the Qery Plan for this query shows the following:
    SELECT STATEMENT (REMOTE)
       SORT (ORDER BY)
          FILTER
             CONNECT BY
                 INDEX (FAST FULL SCAN) EQNDX99 (NON-UNIQUE)
                 TABLE ACESS (BY USER ROWID) EQUIPMENT
                 INDEX (RANGE SCAN) EQNDX999 (NON-UNIQUE)Now it appears to be using both indexes but it is operating through a DBLINK. Is there anything else I can do to increase performance??? It appears to be using the HINT through the link as well.
    Thanks for any help I can get,
    David Miller

    how long does it takes to complete the query?

  • Connect by prior (hierarchical query)

    Hi All,
    Some1 asked me a question which goes like this:
    Source
    emp_no dep_no
    110 10
    110 20
    110 30
    110 40
    120 10
    130 10
    130 20
    write a query to achieve the following output from the above source
    emp_no dept_no
    110 10203040
    120 10
    130 1020
    Now I have come across solutions with 'connect by prior' clauses but I am nt able to understand how oracle is producing that result , Could someone point me to a good article or text that can explain this concept very thoroughly( I have searched on google and got to see many articles but I couldnt able to understand it since these articles were not explaining everything)
    Regards
    Rahul

    You can try this:
    SQL> ed
    Wrote file afiedt.buf
      1  SELECT deptno,MAX(TRIM(SUBSTR(SYS_CONNECT_BY_PATH(empid,','),2)))
      2         KEEP(DENSE_RANK LAST ORDER BY deptno) FROM
      3  (SELECT deptno,empid,ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY deptno) curr,
      4                       ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY deptno) - 1 prev
      5  FROM emp)
      6  CONNECT BY PRIOR curr = prev
      7  AND deptno = PRIOR deptno
      8  START WITH curr = 1
      9* group by deptno
    SQL> /
        DEPTNO MAX(TRIM(SUBSTR(SYS_CONNECT_BY_PATH(EMPID,','),2)))KEEP(DENSE_RANKLASTORDERBYDEPTNO)
            10 1,2,3,4
            20 5,6,7
    SQL> select deptno,empid from emp;
        DEPTNO      EMPID
            10          1
            10          2
            10          3
            10          4
            20          5
            20          6
            20          7
    7 rows selected.
    SQL>

  • Problem Creating a query for a hierarchical tree. [using connect by prior]

    Hi all,
    I have 2 tables.
    box (box_id, box_name)
    item(item_id, item_name, box_id)
    In a box there are several items.
    I want to create a hierachical tree to display items that are present in each box.
    LIKE:
    |---BOX1
    | |----ITEM 1
    | |----ITEM 2
    |
    |---BOX2
    | |----ITEM 1
    | |----ITEM 2
    Currently i am trying this query:
    SELECT -1 state, box_name, 'icon' icon, box_id val
    from box b, item i;
    I don't know what value to put for level, i don't know how to code the 'connect by prior' part.
    Could you please advise me?
    Michaël.
    PS. Then i will eventually use this query in forms builder.

    Note the name of this forum is "SQL Developer *(Not for general SQL/PLSQL questions)*" - so only for issues with the SQL Developer tool. Please post these questions under the dedicated SQL And PL/SQL forum.
    Regards,
    K.

  • Connect to prior sql query

    what is mean by CONNECT TO PRIOR? is it SQL keyword?
    i have tried following query....
    select level,max(sal) from emp
    where level=2
    connect to prior sal>sal
    group by level
    please explain above query........
    thanx ....

    check this also
    http://www.oracle.com/technology/oramag/oracle/05-may/o35asktom.html

  • Connect by Prior in Oracle 8i question

    Need help with building tree-structured query in Oracle 8i (Forms 6i front end if it matters).
    Sample structure and data:
    CREATE TABLE table_list
    my_code NUMBER,
    my_level NUMBER,
    my_description VARCHAR2(60)
    CREATE TABLE table_content
    my_code NUMBER,
    term_code NUMBER,
    term_category VARCHAR2(5)
    INSERT into table_list values (101, 1, 'building');
    INSERT into table_list values (102, 2, 'flat');
    INSERT into table_list values (103, 3, 'living room');
    INSERT into table_list values (104, 3, 'bedroom');
    INSERT into table_list values (105, 3, 'bathroom');
    commit;
    INSERT into table_content values (101, 102, 'Sub');
    INSERT into table_content values (102, 103, 'Sub');
    INSERT into table_content values (102, 104, 'Sub');
    INSERT into table_content values (102, 105, 'Sub');
    commit;
    Need to display data in the following order:
    101 'building' --level one
         102 'flat' --level two
              105 'bathroom' --level three
              104 'bedroom' --level three
              103 'living room' --level three
    *(note alphabetical order in level three)*
    Looks like Oracle 8i does not support table joins for CONNECT BY PRIOR. Please advise!

    And you are correct, it does not display level 1. Do
    you think this is this a database structure problem
    or it could be corrected via query modification?No and yes. It's not a "structure" problem, its a data problem (as I explained above). You always fix data problems by making queries overly complex (hint, hint, I don't suggest doing it this way).
    select tl.my_level, tl.my_description , LPAD(' ',3*(my_level-1)) || substr(tl.my_description, 1, 30) description
    from table_list tl,
    (select term_Code from table_content
    start with my_code in (select my_code from table_list where my_level=1)
    connect by prior term_code = my_code
    ) x
    where x.term_code = tl.my_code
    union all
    select my_level, my_description
    from table_list
    where my_level = 1
    order by 1, 2
    better to add a row to table_content with my_code=null, term_code=101.
    otherwise you'll be pulling stupid nonsense like above with every query from here on out.

  • Connect by Prior - ORA-00600: internal error code, arguments: [kkqcbydrv:1

    Hi,
    We are writing some complex query using Connect by Prior in it.
    When we execute this query on same version of database as that of our client, then the query is executing.
    But when we execute this query at client's side then it raises error -
    ORA-00600: internal error code, arguments: [kkqcbydrv:1] , [] , [] , [] , [] , [] , [] , []
    After searching on metalink,
    We could find two workarounds -
    1. Use a /*+no_unnest*/ hint, but this may have perfomance implications.
    2. alter session set "_optimizer_connect_by_cost_based"=false;
    of which we cant use second workaround as this query is called from a application and not directly from oracle prompt.
    We are working with the first workaround, but what is wondering us is that,
    If same query can work well on our side then why is this query not performing in same way at client's side?
    We are using same version of database, same amount of data is present in development and production databases.
    Then what is causing this error only in priduction?
    Any help in this regard is appreciated.
    Thanks,
    Av.

    You can use the second tip in a database login trigger. But if the metalink ORA-600 diagnostic tool can only give you those workarounds I suggest raising a SR to try and get the bug fixed.
    It may be differing patch levels that cause the difference between the two sites, some subtle difference in temp tablespace, a corrupt block - impossible for us to say but maybe not for Oracle.

Maybe you are looking for