Sys_connect_by_path

Hi All,
I have table X which has two columns.
Data is following
Id Desc
1 My Test
1 My Test1
1 My Test2
2 My Test
2 My Test
I need output as shown below a Pivot.
Id Desc
1 My Test - My Test1 - My Test2
2 My Test - My Test
Number of rows can be dynamic for a given id.
I want to achive through SQL without writing an ORACLE function or procedure. Is there any way we can achive this?
Please help me out.
Thanks in Advance.
GVR.

like this or another way??
with tab_1 as(select 1 sid, 'My Test' sname from dual union all
select 1, 'My Test1' from dual union all
select 1, 'My Test2' from dual union all
select 2, 'My Test' from dual union all
select 2, 'My Test' from dual)
SELECT sid,
LTRIM(MAX(SYS_CONNECT_BY_PATH(sname,'-'))
KEEP (DENSE_RANK LAST ORDER BY curr),'-') AS employees
FROM (SELECT sid, sname,
ROW_NUMBER() OVER (PARTITION BY sid ORDER BY sname) AS curr,
ROW_NUMBER() OVER (PARTITION BY sid ORDER BY sname) -1 AS prev
FROM tab_1)
GROUP BY sid
CONNECT BY prev = PRIOR curr AND sid = PRIOR sid START WITH curr = 1;
or
with tab_1 as(select 1 sid, 'My Test' sname from dual union all
select 1, 'My Test1' from dual union all
select 1, 'My Test2' from dual union all
select 2, 'My Test' from dual union all
select 2, 'My Test' from dual)
SELECT sid,
LTRIM(MAX(SYS_CONNECT_BY_PATH(sname,'-'))
KEEP (DENSE_RANK LAST ORDER BY curr),'-') AS employees
FROM (SELECT sid, sname,
ROW_NUMBER() OVER (PARTITION BY sid ORDER BY sname) AS curr
FROM tab_1)
GROUP BY sid
CONNECT BY curr-1 = PRIOR curr AND sid = PRIOR sid START WITH curr = 1;

Similar Messages

  • How to pass 2nd argument as parameter to SYS_CONNECT_BY_PATH in PLSQL

    Hi All,
    I've the following tables and data:
    CREATE TABLE seg_tab (seg_no NUMBER, seg_value VARCHAR2(10));
    --1st Subset
    INSERT INTO seg_tab VALUES (1,'01');
    --2nd Subset
    INSERT INTO seg_tab VALUES (2,'001');
    INSERT INTO seg_tab VALUES (2,'002');
    --3rd Subset
    INSERT INTO seg_tab VALUES (3,'100040');
    INSERT INTO seg_tab VALUES (3,'100041');
    INSERT INTO seg_tab VALUES (3,'100042');
    INSERT INTO seg_tab VALUES (3,'100043');
    I'm trying to write PLSQL function to generate combination of seg_values using the following code:
    DECLARE l_separator VARCHAR2(10):='.'; BEGIN FOR i IN (           SELECT  SUBSTR ( SYS_CONNECT_BY_PATH (seg_value, l_separator), 2)    AS codes FROM    seg_tab WHERE   CONNECT_BY_ISLEAF  = 1 START WITH  seg_no  = 1 CONNECT BY  seg_no  = PRIOR seg_no + 1) LOOP   DBMS_OUTPUT.PUT_LINE(i.seg_path); END; / 
    When i'm trying to run this code, it is generating the error "Invalid argument to SYS_CONNECT_BY_PATH". When I change the second argument to static value such as '.', it is working fine. The reason I need it that we are using dynamic separator character and is something compulsory.
    Can anyone please help me to rectify it.
    Many Thanks
    Kind Regards,
    Bilal

    Or use a static separator, and replace that separator in the generated path dynamicly.
    Something like:
    replace( substr( sys_connect_by_path( seg_value, '~' ), 2 ), '~', l_separator )
    You just have to use a static value which doesn't occur in your data, seg_value in this case.

  • Hierarchical sys_connect_by_path query needing to process child results

    Application Express 4.0.2.00.06 - DB 10.2
    Hello all!
    I work for an organization having rooms, each with a defined relationship to some or all of the other rooms (some higher, some lower) which must be observed by personnel moving between them.
    I've been tasked with writing an page(extending an existing app in which the relationships are managed) in which if a user provide a list of rooms they wish to visit, a list of hierarchy options will be provided based on the relationship rules between rooms.
    It is implied that given a sourcename/destname pair, sourcename can go to destname and the inverse is also true (destname can come/receive from sourcename)
    This is my sample data set (heavily filtered from actual data);
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME
    28          Ax1          76          G3A
    28          Ax1          27          FGB44
    58          MP23          27          FGB44
    58          MP23          104          MP22
    58          MP23          76          G3A
    76          G3A          27          FGB44
    104          MP22          76          G3A
    104          MP22          58          MP23Using this query, I'm able to build the beginning of my hierarchy.
    SELECT DISTINCT source_roomid,
                    sourcename,
                    dest_roomid,
                    destname,
                    sourcename|| ',' ||REVERSE(sys_connect_by_path(REVERSE(destname),',')) path,
                    (REVERSE(sys_connect_by_path(REVERSE(sourcename),',')))parents,
                    (REVERSE(sys_connect_by_path(REVERSE(destname),',')))children
    FROM           (SELECT source_roomid, A.NAME AS sourcename, dest_roomid, b.NAME AS destname
                    FROM   rm_approved_room_state, rm_room A, rm_room b
                    WHERE  source_roomid IN (27, 28, 58, 76, 104)
                    AND    dest_roomid IN (27, 28, 58, 76, 104)
                    AND    a.roomid = source_roomid
                    AND    b.roomid = dest_roomid)
    --START WITH     source_roomid IN (27, 28, 58, 76, 104)
    CONNECT BY NOCYCLE PRIOR source_roomid = dest_roomid
    order by 1And my initial result set is:
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
    28          Ax1          76          G3A          Ax1,G3A,          Ax1,          G3A,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,
    58          MP23          27          FGB44          MP23,FGB44,          MP23,          FGB44,
    58          MP23          76          G3A          MP23,G3A,          MP23,          G3A,
    58          MP23          76          G3A          MP23,G3A,FGB44,          MP23,G3A,     G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,          MP23,          MP22,
    58          MP23          104          MP22          MP23,MP22,G3A,          MP23,MP22,     MP22,G3A,
    58          MP23          104          MP22          MP23,MP22,G3A,FGB44,     MP23,MP22,G3A,     MP22,G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,MP23,          MP23,MP22,     MP22,MP23,
    76          G3A          27          FGB44          G3A,FGB44,          G3A,          FGB44,
    104          MP22          58          MP23          MP22,MP23,          MP22,          MP23,
    104          MP22          58          MP23          MP22,MP23,FGB44,     MP22,MP23,     MP23,FGB44,
    104          MP22          58          MP23          MP22,MP23,G3A,          MP22,MP23,     MP23,G3A,
    104          MP22          58          MP23          MP22,MP23,G3A,FGB44,     MP22,MP23,G3A,     MP23,G3A,FGB44,
    104          MP22          58          MP23          MP22,MP23,MP22,          MP22,MP23,     MP23,MP22,
    104          MP22          76          G3A          MP22,G3A,          MP22,          G3A,
    104          MP22          76          G3A          MP22,G3A,FGB44,          MP22,G3A,     G3A,FGB44,The challenge for me is that for the hierarchy to be correct, every hierarchy row where level >= 2 needs a check to determine if the latest child can receive from the previous child otherwise filter those lines out. Also, paths where there is duplicated data needs to be removed leaving the longest heirarchy intact.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
      (****THE NEXT LINE IS NOT NECESSARY BECAUSE THE NEXT LINE ALREADY CONTAINS THIS HIERARCHY DATA****)
    28          Ax1          76          G3A          Ax1,G3A,          Ax1,          G3A,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,I also need to pull out instances of where rooms related to each other as in this case.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN
    104          MP22          58          MP23          MP22,MP23,MP22,          MP22,MP23,     MP23,MP22,Leaving this as the anticipated output.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,
    58          MP23          27          FGB44          MP23,FGB44,          MP23,          FGB44,
    58          MP23          76          G3A          MP23,G3A,FGB44,          MP23,G3A,     G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,G3A,          MP23,MP22,     MP22,G3A,
    76          G3A          27          FGB44          G3A,FGB44,          G3A,          FGB44,
    104          MP22          58          MP23          MP22,MP23,G3A,          MP22,MP23,     MP23,G3A,
    104          MP22          76          G3A          MP22,G3A,          MP22,          G3A,Any thoughts on how I might get these last three things done in my hierarchy example?
    Many thanks in advance!
    Paul
    Edited by: pgtaviator on Nov 9, 2011 4:34 PM

    Hi, Paul,
    Sorry, it's unclear what you want.
    pgtaviator wrote:
    Application Express 4.0.2.00.06 - DB 10.2
    Hello all!
    I work for an organization having rooms, each with a defined relationship to some or all of the other rooms (some higher, some lower) which must be observed by personnel moving between them.
    I've been tasked with writing an page(extending an existing app in which the relationships are managed) in which if a user provide a list of rooms they wish to visit, a list of hierarchy options will be provided based on the relationship rules between rooms.
    It is implied that given a sourcename/destname pair, sourcename can go to destname and the inverse is also true (destname can come/receive from sourcename)If "the inverse is also true", why don't the desired results include any paths such as
    G3A,Ax1     or
    FGB44,MP23,MP22     ?
    This is my sample data set (heavily filtered from actual data);
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME
    28          Ax1          76          G3A
    28          Ax1          27          FGB44
    58          MP23          27          FGB44
    58          MP23          104          MP22
    58          MP23          76          G3A
    76          G3A          27          FGB44
    104          MP22          76          G3A
    104          MP22          58          MP23
    Please post CREATE TABLE and INSERT statements for the sample data.
    Is this de-normalized data? That is, does roomid=28 always correspond to name='Ax1', and name='Ax1' always correspond to roomid=28? If not, include examples in your sample data and results, and explain.
    Using this query, I'm able to build the beginning of my hierarchy.
    SELECT DISTINCT source_roomid,
    sourcename,
    dest_roomid,
    destname,
    sourcename|| ',' ||REVERSE(sys_connect_by_path(REVERSE(destname),',')) path,
    (REVERSE(sys_connect_by_path(REVERSE(sourcename),',')))parents,
    (REVERSE(sys_connect_by_path(REVERSE(destname),',')))children
    FROM           (SELECT source_roomid, A.NAME AS sourcename, dest_roomid, b.NAME AS destname
    FROM   rm_approved_room_state, rm_room A, rm_room b
    WHERE  source_roomid IN (27, 28, 58, 76, 104)
    AND    dest_roomid IN (27, 28, 58, 76, 104)
    AND    a.roomid = source_roomid
    AND    b.roomid = dest_roomid)
    --START WITH     source_roomid IN (27, 28, 58, 76, 104)
    CONNECT BY NOCYCLE PRIOR source_roomid = dest_roomid
    order by 1
    Thanks for posting the existing query; that's very helpful.
    REVERSE is not a documented Oracle function. Using undocumneted functions isn't a very good idea. In this case, can't you just change the CONNECT BY clause to:
    CONNECT BY NOCYCLE       source_roomid = PRIOR dest_roomidto get the results you want?
    And my initial result set is:
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
    28          Ax1          76          G3A          Ax1,G3A,          Ax1,          G3A,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,
    58          MP23          27          FGB44          MP23,FGB44,          MP23,          FGB44,
    58          MP23          76          G3A          MP23,G3A,          MP23,          G3A,
    58          MP23          76          G3A          MP23,G3A,FGB44,          MP23,G3A,     G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,          MP23,          MP22,
    58          MP23          104          MP22          MP23,MP22,G3A,          MP23,MP22,     MP22,G3A,
    58          MP23          104          MP22          MP23,MP22,G3A,FGB44,     MP23,MP22,G3A,     MP22,G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,MP23,          MP23,MP22,     MP22,MP23,
    76          G3A          27          FGB44          G3A,FGB44,          G3A,          FGB44,
    104          MP22          58          MP23          MP22,MP23,          MP22,          MP23,
    104          MP22          58          MP23          MP22,MP23,FGB44,     MP22,MP23,     MP23,FGB44,
    104          MP22          58          MP23          MP22,MP23,G3A,          MP22,MP23,     MP23,G3A,
    104          MP22          58          MP23          MP22,MP23,G3A,FGB44,     MP22,MP23,G3A,     MP23,G3A,FGB44,
    104          MP22          58          MP23          MP22,MP23,MP22,          MP22,MP23,     MP23,MP22,
    104          MP22          76          G3A          MP22,G3A,          MP22,          G3A,
    104          MP22          76          G3A          MP22,G3A,FGB44,          MP22,G3A,     G3A,FGB44,The challenge for me is that for the hierarchy to be correct, every hierarchy row where level >= 2 needs a check to determine if the latest child can receive from the previous child otherwise filter those lines out.I don't understand the requirement above at all.
    Also, paths where there is duplicated data needs to be removed leaving the longest heirarchy intact.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
    (****THE NEXT LINE IS NOT NECESSARY BECAUSE THE NEXT LINE ALREADY CONTAINS THIS HIERARCHY DATA****)
    28          Ax1          76          G3A          Ax1,G3A,          Ax1,          G3A,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,
    Are you using "THE NEXT LINE" to mean 2 different things? Do you mean "The line with Ax1,G3A is not wanted because it is a sub-path of Ax1,G3A,FGB44"?
    Why do the desired results include
    MP22,G3A     (which is a sub-path of MP23.MP22,G3A) and
    G3A,FGB44     (which is a sub-path of both Ax1,G3A,FGB44 and MP23,G3A,FGB44)?
    I also need to pull out instances of where rooms related to each other as in this case.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN
    104          MP22          58          MP23          MP22,MP23,MP22,          MP22,MP23,     MP23,MP22,
    When you way "rooms related to each other", do you mean "rooms related to themselves"? It looks like you're saying that no room can occur 2 (or more) times in any path.
    Leaving this as the anticipated output.
    SOURCE_ROOMID     SOURCENAME     DEST_ROOMID     DESTNAME     PATH               PARENTS          CHILDREN     
    28          Ax1          27          FGB44          Ax1,FGB44,          Ax1,          FGB44,
    28          Ax1          76          G3A          Ax1,G3A,FGB44,          Ax1,G3A,     G3A,FGB44,
    58          MP23          27          FGB44          MP23,FGB44,          MP23,          FGB44,
    58          MP23          76          G3A          MP23,G3A,FGB44,          MP23,G3A,     G3A,FGB44,
    58          MP23          104          MP22          MP23,MP22,G3A,          MP23,MP22,     MP22,G3A,
    76          G3A          27          FGB44          G3A,FGB44,          G3A,          FGB44,
    104          MP22          58          MP23          MP22,MP23,G3A,          MP22,MP23,     MP23,G3A,
    104          MP22          76          G3A          MP22,G3A,          MP22,          G3A,
    Why do 3 of the paths end at G3A? Why don't they continue to FGB44 as 2 of the paths do?
    Why is MP23,G3A,FGB44 in the desired output, and not MP22,MP23,G3A,FGB44 (which is longer)?
    Why isn't MP22,MP23,FGB44 in the desired results, but its sub-path MP23,FGB44 is?
    Try describing what you're trying to show in this query, and what each row of the desired result set represents. As far as possible, avoid repeating the explanation you're already used. (Not that there's anything wrong with what you've said so far; it's just that I need all the help I can get to understand the probhlem.)
    Any thoughts on how I might get these last three things done in my hierarchy example?It looks like CONNECT_BY_ISLEAF, and maybe CONNECT_BY_ISCYCLE could help in this problem.
    Regular expressions, or perhaps LIKE, might help in detecting if one path contains another.
    Many thanks in advance!
    Paul
    Edited by: pgtaviator on Nov 9, 2011 4:34 PM

  • ORA-01489 sys_connect_by_path and previous solution not working

    Hi all.
    Oracle version:
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    PL/SQL Release 11.2.0.1.0 - Production
    "CORE     11.2.0.1.0     Production"
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production
    I need to get routes in a map and the associated sum of distances from some point to another.
    map
    --     9
      F ----------E
      | \         |
      |  \2       |6
      |   \   11  |
    14|   C-------D
      |  / \10   /
      | /9  \   /15
      |/     \ /
      A-------B
         7I have a query that correctly gets the routes.
    WITH distances AS
         SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION
         SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION
         SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION
         SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION
         SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION
         SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION
         SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION
         SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION
         SELECT 'F' n1, 'E' n2, 9 d FROM DUAL
    SELECT
         'A'||sys_connect_by_path(n2,'-') path,
         SUBSTR(sys_connect_by_path(d,'+'),2) sum_dist
    FROM distances
    START WITH n1='A'
    CONNECT BY NOCYCLE PRIOR n2=n1;
    A-B          7
    A-B-C          7+10
    A-B-C-D          7+10+11
    A-B-C-D-E     7+10+11+6
    A-B-C-F          7+10+2
    A-B-C-F-E     7+10+2+9
    A-B-D          7+15
    A-B-D-E          7+15+6
    A-C          9
    A-C-D          9+11
    A-C-D-E          9+11+6
    A-C-F          9+2
    A-C-F-E          9+2+9
    A-F          14
    A-F-E          14+9The problem is when there are a lot of nodes, I get an ORA-01489: result of string concatenation is too long.
    I followed this link.
    sys_connect_by_path & to_CLOB
    I built the specified package but apparently is combining elements.
    If it's called just one time.
    WITH distances AS
         SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION
         SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION
         SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION
         SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION
         SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION
         SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION
         SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION
         SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION
         SELECT 'F' n1, 'E' n2, 9 d FROM DUAL
    SELECT
         'A'||'-'||hierarchy.branch(LEVEL,n2,'-') path
    FROM distances
    START WITH n1='A'
    CONNECT BY NOCYCLE PRIOR n2=n1;
    A-B
    A-B-C
    A-B-C-D
    A-B-C-D-E
    A-B-C-F
    A-B-C-F-E
    A-B-D
    A-B-D-E
    A-C
    A-C-D
    A-C-D-E
    A-C-F
    A-C-F-E
    A-FBut if I call it twice in the same query...
    WITH distances AS
         SELECT 'A' n1, 'B' n2, 7 d FROM DUAL UNION
         SELECT 'A' n1, 'C' n2, 9 d FROM DUAL UNION
         SELECT 'A' n1, 'F' n2, 14 d FROM DUAL UNION
         SELECT 'B' n1, 'D' n2, 15 d FROM DUAL UNION
         SELECT 'B' n1, 'C' n2, 10 d FROM DUAL UNION
         SELECT 'C' n1, 'D' n2, 11 d FROM DUAL UNION
         SELECT 'C' n1, 'F' n2, 2 d FROM DUAL UNION
         SELECT 'D' n1, 'E' n2, 6 d FROM DUAL UNION
         SELECT 'F' n1, 'E' n2, 9 d FROM DUAL
    SELECT
         'A'||SUBSTR(hierarchy.branch(LEVEL,n2,'-'),2) path,
         hierarchy.branch(LEVEL,d,'+') sum_dist
    FROM distances
    START WITH n1='A'
    CONNECT BY NOCYCLE PRIOR n2=n1;
    A          7
    A-C          7+10
    A-10-D          7+10+11
    A-10-11-E     7+10+11+6
    A-10-F          7+10+2
    A-10-2-E     7+10+2+9
    A-D          7+15
    A-15-E          7+15+6
    A          9
    A-D          9+11
    A-11-E          9+11+6
    A-F          9+2
    A-2-E          9+2+9As you can see, is combining the elements (A-10-11-E) node - distance - distance - node
    Do I have to create separate functions in the package, one per column?, or is there another way to solve this problem?, or even better, another way to solve the original problem (ORA-01489)
    Thanks a lot.
    Regards.
    Package code (by Solomon Yakobson):
    CREATE OR REPLACE
      PACKAGE Hierarchy
        IS
            TYPE BranchTableVarchar2Type IS TABLE OF VARCHAR2(4000)
              INDEX BY BINARY_INTEGER;
            BranchTableVarchar2 BranchTableVarchar2Type;
            TYPE BranchTableClobType IS TABLE OF CLOB
              INDEX BY BINARY_INTEGER;
            BranchTableClob BranchTableClobType;
            FUNCTION Branch(
                            p_Level          IN NUMBER,
                            p_Value          IN VARCHAR2,
                            p_Delimiter      IN VARCHAR2 DEFAULT CHR(0)
              RETURN VARCHAR2;
            PRAGMA RESTRICT_REFERENCES(Branch,WNDS);
            FUNCTION Branch(
                            p_Level          IN NUMBER,
                            p_Value          IN CLOB,
                            p_Delimiter      IN VARCHAR2 DEFAULT CHR(0)
              RETURN CLOB;
            PRAGMA RESTRICT_REFERENCES(Branch,WNDS);
    END Hierarchy;
    CREATE OR REPLACE
      PACKAGE BODY Hierarchy
        IS
            ReturnValueVarchar2 VARCHAR2(4000);
            ReturnValueClob     CLOB;
        FUNCTION Branch(
                        p_Level        IN NUMBER,
                        p_Value        IN VARCHAR2,
                        p_Delimiter    IN VARCHAR2 DEFAULT CHR(0)
          RETURN VARCHAR2
          IS
          BEGIN
              BranchTableVarchar2(p_Level) := p_Value;
              ReturnValueVarchar2          := p_Value;
              FOR I IN REVERSE 1..p_Level - 1 LOOP
                ReturnValueVarchar2 := BranchTableVarchar2(I)|| p_Delimiter || ReturnValueVarchar2;
              END LOOP;
              RETURN ReturnValueVarchar2;
        END Branch;
        FUNCTION Branch(
                        p_Level        IN NUMBER,
                        p_Value        IN CLOB,
                        p_Delimiter    IN VARCHAR2 DEFAULT CHR(0)
          RETURN CLOB
          IS
          BEGIN
              BranchTableClob(p_Level) := p_Value;
              ReturnValueClob          := p_Value;
              FOR I IN REVERSE 1..p_Level - 1 LOOP
                ReturnValueClob := BranchTableClob(I)|| p_Delimiter || ReturnValueClob;
              END LOOP;
              RETURN ReturnValueClob;
        END Branch;
    END Hierarchy;
    /Edited by: sKr on 08-mar-2012 17:29
    Package code added

    Hi,
    sKr wrote:
    Hi all.
    Oracle version:
    Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
    PL/SQL Release 11.2.0.1.0 - Production
    "CORE     11.2.0.1.0     Production"
    TNS for Linux: Version 11.2.0.1.0 - Production
    NLSRTL Version 11.2.0.1.0 - Production
    I need to get routes in a map and the associated sum of distances from some point to another.
    map
    --     9
    F ----------E
    | \         |
    |  \2       |6
    |   \   11  |
    14|   C-------D
    |  / \10   /
    | /9  \   /15
    |/     \ /
    A-------B
    7... I wish we could mark questions as "Helpful" or "Correct". You'd get 10 points for sure.
    Do I have to create separate functions in the package, one per column?,You don't need separate functions. One user-defined function should be enough, just like one built-in version of SYS_CONNECT_BY_PATH is enough. Whatever it has to store internally, it knows to keep a separate copy for every argument that you call it with. The problem with the package, as originally posted, is that there's only one internal variable BranchTableVarchar2. Instead of one variable, make an array of similar variables, and add an optional argument to the branch funtion to tell it which element in that array to use.
    CREATE OR REPLACE
      PACKAGE Hierarchy
        IS
            TYPE BranchTableVarchar2Type IS TABLE OF VARCHAR2(4000)
              INDEX BY BINARY_INTEGER;
            BranchTableVarchar2 BranchTableVarchar2Type;
         TYPE VList     IS TABLE OF BranchTableVarchar2Type          -- ***  NEW  ***
           INDEX BY     BINARY_INTEGER;                         -- ***  NEW  ***
         vl     VList;                                      -- ***  NEW  ***
            TYPE BranchTableClobType IS TABLE OF CLOB
              INDEX BY BINARY_INTEGER;
            BranchTableClob BranchTableClobType;
            FUNCTION Branch(
                            p_Level          IN NUMBER,
                            p_Value          IN VARCHAR2,
                            p_Delimiter      IN VARCHAR2     DEFAULT CHR(0),
                   p_PathNum      IN PLS_INTEGER     DEFAULT     1     -- ***  NEW  ***
              RETURN VARCHAR2;
            PRAGMA RESTRICT_REFERENCES(Branch,WNDS);
            FUNCTION Branch(
                            p_Level          IN NUMBER,
                            p_Value          IN CLOB,
                            p_Delimiter      IN VARCHAR2 DEFAULT CHR(0)
              RETURN CLOB;
            PRAGMA RESTRICT_REFERENCES(Branch,WNDS);
    END Hierarchy;
    SHOW ERRORS
    PROMPT     ==========  FK BODY  ==========
    CREATE OR REPLACE
      PACKAGE BODY Hierarchy
        IS
            ReturnValueVarchar2 VARCHAR2(4000);
            ReturnValueClob     CLOB;
        FUNCTION Branch(
                        p_Level        IN NUMBER,
                        p_Value        IN VARCHAR2,
                        p_Delimiter    IN VARCHAR2       DEFAULT CHR(0),
                  p_PathNum        IN PLS_INTEGER DEFAULT 1     -- ***  NEW  ***
          RETURN VARCHAR2
          IS
          BEGIN
              vl (p_PathNum) (p_Level) := p_Value;               -- ***  CHANGED  ***
              ReturnValueVarchar2          := p_Value;
              FOR I IN REVERSE 1..p_Level - 1 LOOP
                ReturnValueVarchar2 := vl (p_PathNum) (I)          -- ***  CHANGED  ***
                             || p_Delimiter
                         || ReturnValueVarchar2;
              END LOOP;
              RETURN ReturnValueVarchar2;
        END Branch;
        FUNCTION Branch(
                        p_Level        IN NUMBER,
                        p_Value        IN CLOB,
                        p_Delimiter    IN VARCHAR2 DEFAULT CHR(0)
          RETURN CLOB
          IS
          BEGIN
              BranchTableClob(p_Level) := p_Value;
              ReturnValueClob          := p_Value;
              FOR I IN REVERSE 1..p_Level - 1 LOOP
                ReturnValueClob := BranchTableClob(I)|| p_Delimiter || ReturnValueClob;
              END LOOP;
              RETURN ReturnValueClob;
        END Branch;
    END Hierarchy;
    SHOW ERRORSAs you can see, I only changed the VARCHAR2 version. I'll leave changing the CLOB version as an exercise for you.
    When you call branch, pass a unique number for each column of output. If you don't explicitly give a number, it will default to 0.
    Here's your query modified to call it:
    SELECT  'A' || SUBSTR ( hierarchy.branch ( LEVEL
                                           , n2
                    , 2
                    )          AS path
    ,     hierarchy.branch ( LEVEL
                    , d
                    , '+'
                    , 12
                    )     AS sum_dist
    FROM    distances
    START WITH          n1 = 'A'
    CONNECT BY NOCYCLE      PRIOR n2     = n1
    ;For path, I called branch with only 3 arguments, so it's using vl (0) for internal storage for path.
    For sum_dist, I had to use a different integer. I couldn't decide if I should use 1 or 2, so I compromised and used 12. I could have used any integer, except 0.
    Output:
    PATH                           SUM_DIST
    A                              7
    A-C                            7+10
    A-C-D                          7+10+11
    A-C-D-E                        7+10+11+6
    A-C-F                          7+10+2
    A-C-F-E                        7+10+2+9
    A-D                            7+15
    A-D-E                          7+15+6
    A                              9
    A-D                            9+11
    A-D-E                          9+11+6
    A-F                            9+2
    A-F-E                          9+2+9
    A                              14
    A-E                            14+9
    or is there another way to solve this problem?, or even better, another way to solve the original problem (ORA-01489)Since you're calling a user-defined package, you might want to add other features to the package.
    For starters, in addition to a function that returns a string like '7+10+11', it might be handy to have a string that keeps those numbers internally, but returns the actual value 7 + 10 + 11 = 28.
    If you're using this for problems where you want to find the path with the least total d (or the greatest total d, for that matter, but for now let's say you're only interested in the minimum), you might want a function that keeps track of the minimum total d encountered so far for each node. Every time you find a different path to a node, the function could check to see if the total d is better than the previous best. If not, it could return a flag (sort of like CONNECT_BY_ISCYCLE) that tells you not to bother with that path any more.

  • Issue with sys_connect_by_path

    Hi all,
    Let me preface this post with I'm new to Oracle, using 10g, and mostly a self taught SQL person so it's not my strong suit. The overall goal is I'm trying to find folders within an area of our document management system that haven't been touched so we can perform some clean up. What I have to do is first find all active documents and its' parent folder in the hierarchy then compare the active folders to all folders to get my inactive folders. I have the first part of this working with the following:
    SELECT      Distinct(ActiveFolderID)
    FROM        (SELECT DataID, substr(sys_connect_by_path(DataID, '\'), instr(sys_connect_by_path(DataID, '\'),
                        '\', 1,2) + 1, instr(sys_connect_by_path(DataID, '\'), '\',1,3)
                        - instr(sys_connect_by_path(DataID, '\'), '\',1,2)-1) ActiveFolderID
                 FROM DTree
                 START WITH DataID = 9081729
                 CONNECT BY PRIOR DataID = ParentID) dt, DAuditNew da
    WHERE dt.DataID=da.DataID AND DA.PERFORMERID != 11681125 AND da.AuditDate > SysDate - 90Where I run into an issue is when I add the next part to select folders that aren't in the above result:
    SELECT      DataID, Name
    FROM        DTree
    WHERE       SubType=0 AND ParentID=9081729 AND DataID NOT IN (SELECT Distinct(ActiveFolderID)
                        FROM (SELECT DataID, substr(sys_connect_by_path(DataID, '\'), instr(sys_connect_by_path(DataID, '\'),
                                     '\', 1,2) + 1, instr(sys_connect_by_path(DataID, '\'), '\',1,3)
                                     - instr(sys_connect_by_path(DataID, '\'), '\',1,2)-1) ActiveFolderID
                              FROM DTree
                              START WITH DataID = 9081729
                              CONNECT BY PRIOR DataID = ParentID) dt, DAuditNew da
                        WHERE dt.DataID=da.DataID AND DA.PERFORMERID != 11681125 AND da.AuditDate > SysDate - 90)I get the following error:
    ORA-30004: when using SYS_CONNECT_BY_PATH function, cannot have seperator as part of column value
    30004. 00000 - "when using SYS_CONNECT_BY_PATH function, cannot have seperator as part of column value"
    *Cause:   
    *Action:   Use another seperator which does not occur in any column value,
    then retry.
    I know there are no \ in DataID as it a numeric field, but I have tried other seperators with no luck. Any ideas? Hopefully it's not something simple that I screwed up.
    Thanks,
    Bryan

    Hi, Byran,
    One way to get the results you want would be a MINUS operation. If I understand the requirements, you want
    (a) the set of all folders that are one level down from any node called 'root'
    MINUS
    (b) the subset of folders in (a) that have descendants whose names start with 'Activefile' and were audited no more than 90 days ago.
    We can get (a) with a self-join.
    We can get (b) with CONNECT BY, using (a) in the START WITH clause. In Oracle 9, we would have had to use SYS_CONNECT_BY_PATH for this, but starting in Oracle 10 we have CONNECT_BY_ROOT.
    WITH     top_level_folders     AS
         SELECT     c.dataid
         ,     c.name
         FROM     dtree     p
         JOIN     dtree     c  ON     c.parentid     = p.dataid
         WHERE     p.name     = 'root'
    ,     active_files     AS
         SELECT     CONNECT_BY_ROOT dataid     AS top_dataid
         ,     CONNECT_BY_ROOT name     AS top_name
         ,     dataid
         FROM     dtree
         WHERE     name     LIKE 'Activefile%'
         START WITH     dataid IN (
                             SELECT  dataid
                             FROM     top_level_folders
         CONNECT BY     parentid     = PRIOR dataid
    SELECT       dataid
    ,       name
    FROM       top_level_folders
         MINUS
    SELECT       af.top_dataid
    ,       af.top_name
    FROM       active_files     af
    JOIN       dauditnew     dan  ON     af.dataid     = dan.dataid
    WHERE       dan.auditdate     > SYSDATE - 90
    ORDER BY  dataid
    ;Output (when run on Feb. 2, 2012):
    `   DATAID NAME
             2 folder1
             3 folder2
             5 folder4As you can see, I did the filtering for audit dates near the end of the query. Depending on your data and your requirements, there might be a more efficient way to do it near the start of the query. The CONNECT BY is probably going to be the slow part of his job, so if there's some way to eliminate rows before that, it would probably be more efficient that running a longer CONNECT BY part, only to discard some of the results at the end. You don't want to do a join in the same sub-query as the CONNECT BY; that's extremely inefficient.
    I still have no idea why your original query was getting that ORA-30004 error. I'd be interested in finding out. I can't run the original query, apparantly because you simplified the tables for posting. If you can post a test case that gets the error using SYS_CONNECT_BY_PATH, I'll see if I can find out what caused it.

  • SYS_CONNECT_BY_PATH performance issue!!

    I am using SYS_CONNECT_BY_PATH to get the hierarchical structure from a table. But its taking much much more time.
    I am using as follows:
    SELECT DISTINCT trim(h.my_id) AS my_ID,sys_connect_by_path (trim(my_id),'.') AS hierarchy
    from (some inline select query) h
    connect by prior h.my_id=h.super_id
    Please someone advice me if there is any way for optimizing sys_connect_by_path() in general. Thanks.

    Hi,
    If you don't have a START WITH clause, you'll start with every row in your table. Is that really what you need to do?
    It's also very suspicious that you need SELECT DISTINCT. SELECT DISTINCT is sometimes an attempt to conceal the defects caused by a problem elsewhere (such as lacking a START WITH clause).
    Please explain exactly what you're trying to do. Post a little sample data and the results you need to get from that data.

  • Sys_connect_by_path problem

    Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
    PL/SQL Release 11.1.0.7.0 - Production
    CORE    11.1.0.7.0      Production
    TNS for IBM/AIX RISC System/6000: Version 11.1.0.7.0 - ProductionHow come
    SYS_CONNECT_BY_PATH (file_name, ',#')works fine but
    SYS_CONNECT_BY_PATH (file_name, ',' || '#')fails with a
    ORA-30003: illegal parameter in SYS_CONNECT_BY_PATH functionerror? Can anyone provide some explanation?
    Thanks.

    REPLACE would work on SYS_CONNECT_BY_PATH results as well, afaik.
    Using some example that I found in my cache:
    SQL> with table1 as (
      2   select 10001 afield, 'Test Record 1' bfield, 'Hello' cfield from dual union all
      3   select 10002, 'Test Record 2', 'Hello' from dual union all
      4   select 10003, 'Test Record 3', 'Hello' from dual
      5   )
      6   ,   table2 as (
      7   select '00001' afield, 'Sample Data 1' bfield, 10001 cfield from dual union all
      8   select '00002', 'Sample Data 2', 10001 from dual union all
      9   select '00003', 'Sample Data 3a', 10002 from dual union all -- Duplicate
    10   select '00003', 'Sample Data 3b', 10002 from dual union all -- Duplicate
    11   select '00004', 'Sample Data 4', 10003 from dual union all
    12   select '00005', 'Sample Data 5', 10003 from dual union all
    13   select '00006', 'Sample Data 6', 10003 from dual
    14   )
    15   --
    16   -- actual query:
    17   --
    18  select afield
    19  ,      bfield
    20  ,      ltrim(sys_connect_by_path(bafield, ',')) scbp1
    21  --,      ltrim(sys_connect_by_path(bafield, chr(10)), chr(10)) scbp2  --<< gives an ora-30003
    22  ,      replace(ltrim(sys_connect_by_path(bafield, ','), ','), ',', chr(10)) scbp3
    23  from ( select a.afield
    24         ,      a.bfield
    25         ,      b.afield bafield
    26         ,      row_number() over (partition by a.afield order by to_number(b.afield)) rn
    27         ,      count(distinct b.afield) over (partition by a.afield) recs
    28         from   table1 a
    29         ,      table2 b
    30         where  a.afield = b.cfield
    31       )
    32  where rn=recs
    33  start with rn=1
    34  connect by afield = prior afield
    35         and rn = prior rn+1;
        AFIELD BFIELD        SCBP1                                              SCBP3
         10001 Test Record 1 ,00001,00002                                       00001
                                                                                00002
         10002 Test Record 2 ,00003                                             00003
         10003 Test Record 3 ,00004,00005,00006                                 00004
                                                                                00005
                                                                                00006
    3 rows selected.Docs say:
    "Both column and char can be any of the datatypes CHAR, VARCHAR2, NCHAR, or NVARCHAR2. The string returned is of VARCHAR2 datatype and is in the same character set as column."
    http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/functions171.htm#SQLRF06116
    So, I guess 'char' just cannot be an expression (or a subquery or a function or containing operators etc...).

  • SYS_CONNECT_BY_PATH Upside-down (over Bills of Material)

    Hello all,
    I'm trying to use this function, in order to check the most upper assemblies for a component.
    The input I enter us a lower component, which I'd like to know who it the top assembly for it.
    I'm using the following select:
    select distinct(LPAD(' ', 2*level-1)||SYS_CONNECT_BY_PATH((mcil_fe_work_plan.get_item_name(asy.assembly_item_id,2)), '/')) "Hierarchy",
    mcil_fe_work_plan.get_item_name(com.component_item_id,2) "Last level"
    from bom_bill_of_materials asy, bom_inventory_components com
    where asy.bill_sequence_id = com.bill_sequence_id
    start with com.component_item_id = 73805
    connect by NOCYCLE prior asy.assembly_item_id = com.component_item_id
    I'm getting thousands of line, for example:
    /FLF5559A/F2180A/INFOTAC F2180A
    /FLF5559A/FUF1025A FLF5559A
    /FLF5559A/FUF1602A FLF5559A
    /FLF5559A/FUF1602A/F5110A/F5110A-MM/F5110A-MM*12382 F5110A-MM
    /FLF5559A/FUF1602A/F5110A/F5110ASP96910/F5110ASP96910-MM F5110ASP96910
    /FLF5559A/FUF1602A/F5110A/F5110A-MM*8036 F5110A
    /FLF5559A/FUF1602A/F5149B/F5149B-MM/F5149_-MDL/F5149_ F5149_-MDL
    I want to know Only the top level assembly, not only one level above or to get all the tree's structure.
    Any idea guyes?
    Best Regards,
    Tomer.
    Edited by: tomeriko on Mar 24, 2009 1:07 AM

    SCOTT schema is installed as standard with Oracle although the user login may be locked initially unless the DBA has unlocked it.
    SQL> select * from emp;
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
          7369 SMITH      CLERK           7902 17-DEC-80        800                    20
          7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
          7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
          7566 JONES      MANAGER         7839 02-APR-81       2975                    20
          7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
          7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
          7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
          7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
          7839 KING       PRESIDENT            17-NOV-81       5000                    10
          7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
          7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
          7900 JAMES      CLERK           7698 03-DEC-81        950                    30
          7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
          7934 MILLER     CLERK           7782 23-JAN-82       1300                    10
    14 rows selected.
    SQL> col d_ename format a20
    SQL> col path format a30
    SQL> col a_ename format a20
    SQL> ed
    Wrote file afiedt.buf
      1  SELECT     CONNECT_BY_ROOT ename                   AS d_ename
      2  ,  SYS_CONNECT_BY_PATH (ename, '/')        AS path         -- For illustration only
      3  ,  ename                                   AS a_ename
      4  FROM       scott.emp
      5  WHERE      CONNECT_BY_ISLEAF       = 1
      6  START WITH ename   = '&starting_ename'
      7* CONNECT BY empno   = PRIOR mgr
    SQL> /
    Enter value for starting_ename: SCOTT
    old   6: START WITH     ename   = '&starting_ename'
    new   6: START WITH     ename   = 'SCOTT'
    D_ENAME              PATH                           A_ENAME
    SCOTT                /SCOTT/JONES/KING              KING
    SQL>;)

  • Help with sys_connect_by_path

    Hi,
    I'm newbie in retrieving hierarchical data, so please help with this.
    I have Oracle 8.1.7.0.0.
    I have a view with this kind of data:
    TYP     COMP_TYP
    005     010
    010     005
    020     010
    030     010
    030     020
    040     005
    060     040
    065     005
    070     19
    080     070
    090     070
    095     030
    095     060
    095     065
    100     005
    100     030
    100     060
    100     065
    Now, the client wants to see these data in hierarchical way.
    I tried this:
    SELECT
    LPAD(' ', 2*LEVEL, ' ' ) ||cbc.TYP TYP
    ,sys_connect_by_path( cbc.COMP_TYP, '/' ) COMP_TYP
    FROM v_cls_test cbc
    START WITH cbc.TYP='095'
    CONNECT BY PRIOR cbc.TYP = cbc.COMP_TYP
    in this case the desired result should be like
    095
    030
    010
    005
    020
    010
    060
    040
    005
    065
    005
    but I'm not getting the desired result.
    Thanks in advance for any input.
    Best regards,
    Marius

    Hi,
    There is a problem with your data
    TYP COMP_TYP
    005 010 --> should this pair be 005 NULL ?? otherwise it's circullar
    010 005
    If you change the first pair one to 005 NULL and modify your query as follows:
    SELECT
    LPAD(' ', 2*LEVEL, ' *' ) ||cbc.TYP TYP
    ,sys_connect_by_path( cbc.TYP, '/' ) PATH
    FROM v_cls_test cbc
    START WITH cbc.COMP_TYPE IS NULL
    CONNECT BY PRIOR cbc.TYP = cbc.COMP_TYP
    you'll get the following output
    TYP PATH
    * 005     /005
    *** 010     /005/010
    ***** 020     /005/010/020
    ******* 030     /005/010/020/030
    ********* 095     /005/010/020/030/095
    ********* 100     /005/010/020/030/100
    Rado

  • Pivoting using sys_connect_by_path

    Can you please let me know how to get this output using sys_connect_by_path hierarchical function ?
    JOB DEPT_10 DEPT_20 DEPT_30 DEPT_40
    CLERK 1 2 1 (null)
    SALESMAN (null) (null) 4 (null)
    PRESIDENT 1 (null) (null) (null)
    MANAGER 1 1 1 (null)
    ANALYST (null) 2 (null) (null)
    I know how to acheive this by decode function.Even I have the query ready .
    select job,
    max( decode( deptno, 10, cnt, null ) ) dept_10,
    max( decode( deptno, 20, cnt, null ) ) dept_20,
    max( decode( deptno, 30, cnt, null ) ) dept_30,
    max( decode( deptno, 40, cnt, null ) ) dept_40
    from ( select job, deptno, count(*) cnt from emp group by job, deptno )
    group by job
    But my requirement is to get the same output by using SYS_CONNECT_BY_PATH.
    Please let me know the query if its possible.Else let me know the reason why we cant do .

    Hi,
    Welcome to thre forum!
    If you're using Oracle 11, then SELECT ... PIVOT can help do what you want. In any version, you can do something like what you're already doing, though you don't need a sub-query:
    SELECT       job
    ,       SUM (DECODE (deptno, 10, 1))     AS dept_10
    ,       SUM (DECODE (deptno, 20, 1))     AS dept_20
    ,       SUM (DECODE (deptno, 30, 1))     AS dept_30
    ,       SUM (DECODE (deptno, 40, 1))     AS dept_40
    FROM       scott.emp
    GROUP BY  job
    ORDER BY  job     -- If wanted
    ;Either way, SYS_CONNECT_BY_PATH doesn't help any.
    The one reason why you might want to use SYS_CONNECT_BY_PATH is if you didn't know how many different departments there might be. In that case, you could do something like this:
    WITH     got_cnt          AS
         SELECT       e.job
         ,       d.deptno
         ,       NULLIF (COUNT (e.deptno), 0)               AS cnt
         ,       DENSE_RANK () OVER (ORDER BY d.deptno)     AS d_num
         FROM             scott.dept  d
         LEFT OUTER JOIN  scott.emp   e   PARTITION BY (e.job)
                                            ON  d.deptno = e.deptno
         GROUP BY  e.job
         ,            d.deptno
    SELECT       job
    ,       REPLACE ( SYS_CONNECT_BY_PATH ( NVL2 ( cnt
                                          , TO_CHAR (cnt, '9999')
                )          AS all_cnts
    FROM       got_cnt
    WHERE       CONNECT_BY_ISLEAF     = 1
    START WITH     d_num     = 1
    CONNECT BY     d_num     = PRIOR d_num + 1
         AND     job     = PRIOR job
    ORDER BY  job
    ;As you can see, it's quite a bit more complicated than what you already have, and it's less efficient.
    Also, it doesn't produce separate columns for each depararment. All the departments are concatenated together, formatted so they look like separate columns. Also, the query above doesn't have a header identifiyuing which department corresponds to each "column" , but you could fix that by doing a UNION with another CONNECT BY query to generate a header row.
    To get truly separate columns, you could use various string manipulation techniques to split the results of SYS_CONNECT_BY_PATH into separate columns, but that requires knowing exactly how many departments to expect, which defeats the purpose of using SYS_CONNECT_BY_PATH.

  • Sys_connect_by_path over db link causes ora-29900

    I have a query that uses sys_connect_by_path. It works fine when run from the database where the table resides. When I try to run the same query from another database over a db link, I get the following error:
    ora-29900: operator binding does not exist
    ora-06553: pls-306: wrong number or types of arguments in call to 'PATH'
    Any ideas? Workarounds?

    Are the two databases running the same Oracle version?

  • SQL Query help ( On connect By level clause)

    Hi all,
    I have this query developed with data in with clause.
    With dat As
      select '@AAA @SSS @DDD' col1 from dual union all
      select '@ZZZ @XXX @TTT @RRR @ZZA' col1 from dual
    Select regexp_substr( col1 , '[^@][A-Z]+',1,level) Show from dat
    connect by level  <= regexp_count(col1, '@');Current output :-
    SHOW
    AAA
    SSS
    DDD
    RRR
    ZZA
    TTT
    RRR
    ZZA
    XXX
    DDD
    RRR
    SHOW
    ZZA
    TTT
    RRR
    ZZA
    . . .1st row comes fine, But next row data is getting duplicated. And total record count = 30. I tried with some but didn't work.
    Expected output :-
    SHOW
    AAA
    SSS
    DDD
    ZZZ
    XXX
    TTT
    RRR
    ZZAI need some change on my query and I am not able to find that. So anybody can add on that or can also provide some different solution too.
    Thanks!
    Ashutosh

    Hi,
    When you use something like "CONNECT BY LEVEL <= x", then at least one of the following must be true:
    (a) the table has no more than 1 row
    (b) there are other conditions in the CONNECT BY clause, or
    (c) you know what you are doing.
    To help see why, run this query
    SELECT     SYS_CONNECT_BY_PATH (dname, '/')     AS path
    ,     LEVEL
    FROM     scott.dept
    CONNECT BY     LEVEL <= 3
    ;and study the results:
    PATH                                     LEVEL
    /ACCOUNTING                                  1
    /ACCOUNTING/ACCOUNTING                       2
    /ACCOUNTING/ACCOUNTING/ACCOUNTING            3
    /ACCOUNTING/ACCOUNTING/RESEARCH              3
    /ACCOUNTING/ACCOUNTING/SALES                 3
    /ACCOUNTING/ACCOUNTING/OPERATIONS            3
    /ACCOUNTING/RESEARCH                         2
    /ACCOUNTING/RESEARCH/ACCOUNTING              3
    /ACCOUNTING/RESEARCH/RESEARCH                3
    /ACCOUNTING/RESEARCH/SALES                   3
    /ACCOUNTING/RESEARCH/OPERATIONS              3
    /ACCOUNTING/SALES                            2
    /ACCOUNTING/SALES/ACCOUNTING                 3
    84 rows selected.

  • Help: How to create a query that transpose the column content?

    Here, suppose that I have two tables
    TAB_A:
    ID     TYPE
    1     AA
    1     AB
    1     AC
    2     BA
    2     BB
    2     BC
    2     BD
    I'd like to create a query that gives result as:
    ID     TYPE
    1     AA AB AC
    2     BA BB BC BD Any suggestions?
    Thank you in advance.
    Jimmy

    Hi
    Try this:
    SELECT id,
    replace(LTRIM(MAX(SYS_CONNECT_BY_PATH(type,'*'))
    KEEP (DENSE_RANK LAST ORDER BY curr),'*'),'*', ', ') AS type
    FROM (SELECT id, type,
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY type) AS curr,
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY type) -1 AS prev
    FROM tab_a)
    GROUP BY id
    CONNECT BY prev = PRIOR curr AND id = PRIOR id
    START WITH curr = 1;
    Ott Karesz
    http://www.trendo-kft.hu

  • How To Concatenate Column Values from Multiple Rows into a Single Column?

    How do I create a SQL query that will concatenate column values from multiple rows into a single column?
    Last First Code
    Lesand Danny 1
    Lesand Danny 2
    Lesand Danny 3
    Benedi Eric 7
    Benedi Eric 14
    Result should look like:
    Last First Codes
    Lesand Danny 1,2,3
    Benedi Eric 7,14
    Thanks,
    David Johnson

    Starting with Oracle 9i
    select last, first, substr(max(sys_connect_by_path(code,',')),2) codes
    from
    (select last, first, code, row_number() over(partition by last, first order by code) rn
    from a)
    connect by last = prior last and first = prior first and prior rn = rn -1
    start with rn = 1
    group by last, first
    LAST       FIRST      CODES                                                                                                                                                                                                  
    Lesand         Danny          1,2,3
    Benedi         Eric           7,14Regards
    Dmytro

  • Concatenating values in one row

    I need to write a function that will give me a concatenated list of all the records where gurmail_matl_code_mod like '8%'
    This query is giving me those results:
    GURMAIL_PIDM     CODE1     CODE2
    1135711          
    1135711          8IBD
    1135711     8IBW     
    I want something like this 1135711 8IBW 8IBD in one row.
    select
    gurmail_pidm,
    max(decode(rn,1,gurmail_matl_code_mod )) code1,
    max(decode(rn,2,gurmail_matl_code_mod )) code2
    from (select gurmail_pidm,
                  gurmail_matl_code_mod,
                  row_number() over (partition by gurmail_pidm order by gurmail_matl_code_mod desc) rn
                  from
                      (select  gurmail_pidm,gurmail_matl_code_mod
                               from saturn.spriden,
                                    general.gurmail
                                    where spriden_pidm = gurmail_pidm
                                    and spriden_change_ind is null
                                    and gurmail_matl_code_mod  like '8%'
                                    and gurmail_pidm = 1135711
                                    and GURMAIL_DATE_PRINTED is null
                                    and gurmail_matl_code_mod is not null))
                                    group by gurmail_pidm, gurmail_matl_code_mod   How I can modify this query or let me know if you have other ideas..
    Thank you

    Hello
    try this,
    SQL>  with tab as(Select 1135711 GURMAIL_PIDM, Null CODE1 from dual Union All
      2               Select 1135711 GURMAIL_PIDM, '8IBD' CODE1 from dual Union All
      3               Select 1135711 GURMAIL_PIDM, '8IBW' CODE1 from dual)
      4  SELECT GURMAIL_PIDM || sys_connect_by_path(CODE1,' ') Result
      5    FROM (SELECT GURMAIL_PIDM
      6                ,code1
      7                ,row_number() over(Partition BY GURMAIL_PIDM Order BY GURMAIL_PIDM) rn
      8            FROM tab)
      9   WHERE connect_by_isleaf = 1
    10   Start With rn = 1
    11  Connect BY Prior rn = rn - 1;
    RESULT
    1135711  8IBW 8IBDHope this helps
    Christian Balz

Maybe you are looking for