Hierarchical Query with Rollup Sum (CONNECT BY with GROUP BY ROLLUP)

Hi all,
Imagine the following scenario: i have an ACCOUNT table which holds accounts and their hierarchy (currently 5 levels), and a BALANCE table which holds balance records for the accounts. Only CHILD accounts (level 5) have records in the BALANCE table. Simple example:
CREATE TABLE accounts (account_code VARCHAR2(30), parent_account VARCHAR2(30), account_desc VARCHAR2(400));
CREATE TABLE balances (account_code VARCHAR2(30), balance_amount NUMBER(18,2));
INSERT INTO ACCOUNTS VALUES ('TOT',NULL,'Total');
INSERT INTO ACCOUNTS VALUES ('ANA1','TOT','General Expenses');
INSERT INTO ACCOUNTS VALUES ('4801001','ANA1','Small Expenses');
INSERT INTO ACCOUNTS VALUES ('4801002','ANA1','Transportation');
INSERT INTO ACCOUNTS VALUES ('ANA2','TOT','Health Expenses');
INSERT INTO ACCOUNTS VALUES ('4802001','ANA2','Healthcare');
INSERT INTO ACCOUNTS VALUES ('4802002','ANA2','Facilities');
INSERT INTO BALANCES VALUES ('4801001', 2000);
INSERT INTO BALANCES VALUES ('4801002', 1000);
INSERT INTO BALANCES VALUES ('4802001', 3000);
INSERT INTO BALANCES VALUES ('4802002', 4000);What i need in this scenario is to run a hierarchical query, where for each node i compute the sum of all its children (In LEAF nodes which are the child accounts, this sum is the value in BALANCES itself). Final Result would be:
TOT -> 10000
  ANA1 -> 3000
    4801001 -> 2000
    4801001 -> 1000
  ANA2 -> 7000
    4802001 -> 3000
    4802002 -> 4000I have tried various ways, and found out a workaround which works for a fixed amount of levels, basically it builds the hierarchy and computes the SYS_CONNECT_BY_PATH, then splits this as a regular expression and uses GROUP BY ROLLUP to compute the higher levels. Then i assemble it again, now with the computed values. Below is the example query:
select level
    , NVL (vfinal.child_account,'TOTAL') ||' - '||
                        ( SELECT account_desc
                            FROM accounts
                           WHERE account_code = vfinal.child_acct ) account_name
     , to_char(sum_bal, 'fm999g999g999g990') as rolled_up_balance
  from
select coalesce( princ.lvl3, princ.lvl2, princ.lvl1 ) child_acct
     , DECODE ( princ.lvl2 , NULL
                                 , NULL
                                 , DECODE ( princ.conta_lvl3, NULL
                                 , princ.conta_lvl1,princ.conta_lvl2 ) ) parent_acct
     , sum(princ.balance_amount) sum_bal
from (
select hier.lvl1
     , hier.lvl2
     , hier.lvl3
     , hier.parent_account
     , hier.account_code child_acc
     , bal.balance_amount
  from ( select level 
              , sys_connect_by_path( account_code, '/' ) hierarchy_acct
              , REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,3) lvl3
              , REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,2) lvl2
              , REGEXP_SUBSTR(sys_connect_by_path( account_code, '/' ),'[^/]+',1,1) lvl1
              , account_code
              , parent_account 
           from accounts acc
           where level <= 3
           start with parent_account is null
           connect by nocycle prior account = parent_account
           order siblings by parent_account
           ) hier
      , balances  bal
  where bal.cod_conta  = hier.account_code
) princ
where princ.lvl1 is not null
group by rollup ( princ.lvl1
                , princ.lvl2
                , princ.lvl3 )
order by princ.conta_lvl1
       , princ.conta_lvl2
       , princ.conta_lvl3
) vfinal
where child_acct is not null
start with parent_acct is null
connect by nocycle prior child_acct = parent_acctAll said and done, what i need is to do the same thing for infinite levels, because this query has 3 fixed levels. Do you know how can i structure a new query where, independently of the number of levels, the parent sums are all rolled up like this?
Thanks a lot in advance! Best Regards!
Thiago
Edited by: Thiago on Sep 6, 2011 11:31 AM
Edited by: Thiago on Sep 6, 2011 1:01 PM

Hi,
Thiago wrote:
Hi all,
Imagine the following scenario: i have an ACCOUNT table which holds accounts and their hierarchy (currently 5 levels), and a BALANCE table which holds balance records for the accounts. Only CHILD accounts (level 5) have records in the BALANCE table. Simple example:
CREATE TABLE accounts (account_code VARCHAR2(30), parent_account VARCHAR2(30), account_desc VARCHAR2(400));
CREATE TABLE balances (account_code VARCHAR2(30), balance_amount NUMBER(18,2));
INSERT INTO ACCOUNTS ('TOT',NULL,'Total');
INSERT INTO ACCOUNTS ('ANA1','TOT','General Expenses');
INSERT INTO ACCOUNTS ('4801001','ANA1','Small Expenses');
INSERT INTO ACCOUNTS ('4801002','ANA1','Transportation');
INSERT INTO ACCOUNTS ('ANA2','TOT','Health Expenses');
INSERT INTO ACCOUNTS ('4802001','ANA2','Healthcare');
INSERT INTO ACCOUNTS ('4802002','ANA2','Facilities');
INSERT INTO BALANCES ('4801001', 2000);
INSERT INTO BALANCES ('4801001', 1000);
INSERT INTO BALANCES ('4802001', 3000);
INSERT INTO BALANCES ('4802001', 4000);
Thanks for posting the CREATE TABLE and INSERT statements. Remember why you do it: so that the people who want to help you can re-create the problem and test their ideas. If the statments don't work, then they are not so useful. None of the INSERT statements you posted work: they all need a VALUES keyword. Please test those statments before you post them.
Also, make sure that the reuslts you post correspond to the sample data you post. In your sample data, there are no rows in balances for account_codes '4801002' or '4802002'.
I think you want something like this:
WITH  connect_by_results      AS
     SELECT     CONNECT_BY_ROOT account_code     AS root_account_code
     ,     account_code
     FROM     accounts
                         -- NOTE: No START WITH clause
     CONNECT BY     parent_account     = PRIOR account_code
SELECT       c.root_account_code     || ' -> '
                      || TO_CHAR (SUM (b.balance_amount))     AS txt
FROM           connect_by_results  c
LEFT OUTER JOIN      balances          b  ON  c.account_code = b.account_code
GROUP BY  c.root_account_code
;

Similar Messages

  • Query Help required to Connect JDT1 with OINV tables

    Dear Experts,
    I have the following query which gives me the customer ageing report. I want some addtional fields from the OINV table and the document numbering table like Document Series Name, AR Invoice document Number,AR invoice remarks, BP Projects Number ( filled in accounting tab in BP projects) and in the query in Reference 1 column its giving the Invoice Numbers as posted in the Journal but for manual Journal Entries it not giving the Journal Number which I also want to be shown in Ref 1 or a seperat field.
    The Query is as under :
    select OCRD.cardcode 'Supplier Code',OCRD.cardname 'Name',sysdeb 'Debit Amount',syscred 'Credit Amount',
    case JDT1.transtype
    when '13' then 'INV'
    when '14' then 'AR CN'
    when '24' then 'INCOMING'
    else 'Other'
    end 'Type',
    Ref1,
    fccurrency 'BP Currency',
    CONVERT(VARCHAR(10), refdate, 103)'Posting Date' ,
    CONVERT(VARCHAR(10), duedate, 103) 'Due Date',
    CONVERT(VARCHAR(10), taxdate, 103) 'Doc Date' ,
    CASE
    when (DATEDIFF(dd,refdate,current_timestamp))+1 < 31
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "0-30 days",
    case when ((datediff(dd,refdate,current_timestamp))+1 > 30
    and (datediff(dd,refdate,current_timestamp))+1< 61)
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "31 to 60 days",
    case when ((datediff(dd,refdate,current_timestamp))+1 > 60
    and (datediff(dd,refdate,current_timestamp))+1< 91)
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "61 to 90 days",
    CASE
    when (DATEDIFF(dd,refdate,current_timestamp))+1 > 90
    then
    case
    when syscred= 0 then sysdeb
    when sysdeb= 0 then syscred * - 1
    end
    end "90 + days"
    from JDT1,OCRD where JDT1.shortname = OCRD.cardcode and cardtype = 'c' and intrnmatch = '0'
    ORDER BY OCRD.CARDCODE, taxdate
    Would appreciate if you can help me to get a solution in it.
    Regards,
    Kamlesh

    Dear Gordon,
    While executing the followings modified query it giving an error of
    Incorrect Syntax near the keyword 'to' and incorrect Syntax near 'Series'
    the query is as under :
    {select OCRD.cardcode 'Supplier Code',OCRD.cardname 'Name',sysdeb 'Debit Amount',syscred 'Credit Amount',
    case l.transtype
    when '13' then 'INV'
    when '14' then 'AR CN'
    when '24' then 'INCOMING'
    else 'Other'
    end 'Type',
    j.BaseRef'Trans #',
    case l.transtype
    when '13' then
    (Select Comments from OINV where OINV.Transid=j.Transid)
    else '-'
    end 'Inv.Rem.',
    (Select SeriesName From NNM1 Where Series=j.DocSeries and ObjectCode=l.TransType)'Series',
    to
    (Select Isnull(SeriesName, 'Manual') From NNM1 Where Series=j.DocSeries and ObjectCode=l.TransType)'Series',
    l.Ref1,
    fccurrency 'BP Currency',
    CONVERT(VARCHAR(10), l.refdate, 103)'Posting Date' ,
    CONVERT(VARCHAR(10), l.duedate, 103) 'Due Date',
    CONVERT(VARCHAR(10), l.taxdate, 103) 'Doc Date' ,
    CASE
    when (DATEDIFF(dd,l.refdate,current_timestamp))+1 < 31
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "0-30 days",
    case when ((datediff(dd,l.refdate,current_timestamp))+1 > 30
    and (datediff(dd,l.refdate,current_timestamp))+1< 61)
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "31 to 60 days",
    case when ((datediff(dd,l.refdate,current_timestamp))+1 > 60
    and (datediff(dd,l.refdate,current_timestamp))+1< 91)
    then
    case
    when syscred <> 0 then syscred * - 1
    else sysdeb
    end
    end "61 to 90 days",
    CASE
    when (DATEDIFF(dd,l.refdate,current_timestamp))+1 > 90
    then
    case
    when syscred= 0 then sysdeb
    when sysdeb= 0 then syscred * - 1
    end
    end "90 + days"
    from JDT1 l
    Inner Join OJDT j On j.TransId=l.TransId
    ,OCRD where l.shortname = OCRD.cardcode and cardtype = 'c' and intrnmatch = '0'
    ORDER BY OCRD.CARDCODE, l.taxdate}
    Regards,
    Kamlesh

  • Macbook can't be found with any internet connection except with wi-fi turned on

    Just weard! - I can't find my macbook on find my iphone without wi-fi turned on.
    Why can and is  it normal my macbook only can be found on "find my iphone" when wifi is on while I still have another internet connection activated on my mac without wi-fi??
    Is there something one can do to find my mac - if stolen - when it has any kind of internet connection with wi-fi turned off???

    FaceTime, Game Center, Messages: Troubleshooting sign in issues

  • Cannot connect iPhoto with fotostream, Cannot connect iPhoto with fotostream

    What can be the reason?

    HI JOEL P�REZ�
    I connect like SCOTT, SYSDBA AND OTHER USERS TO THE DATABASE
    CERTAINLY, I DISCONNECT THE SYSMAN USER FROM THE THE DBA STUDIO SESSION USERS.
    THE DATABASE HAS A PASSWORD, I ASSUME, YOU REFER TO PASSWORDFILE TO A PATH PROFILE DATABASE.
    I JUST WANT CONNECT TO THE DATABASE LIKE SYSMAN IN THE SERVER, NOT LIKE CLIENT.
    [i]CAN YOU HELP ME TO CONNECT TO THE DATA BASE FROM OEM CONSOLE?.
    THE WIZARD FOR A NEW NODE DOESN'T HELP ME.
    THE PROFILE TNSNAMES IS OK.
    DAVE

  • Router Compatible with WRT54G Antenna Connection

    I have to replace our WRT54G router--it's currently connected to a power booster and and omni-directional antenna.  Is there a router with an antenna connection compatible with the WRT54G--preferably a single antenna model?
    Thx in advance,
    David Miller

    Here are some...
    http://www.google.com/search?q=routers+with+antennas&sourceid=ie7&rls=com.microsoft:en-us:IE-SearchB...

  • Customized heading in the Group by Rollup clause

    I have a table with the following data.
    SQL> select region, accname, secname, col1 from acc;
    REGION ACCNAME SECNAME COL1
    region1 acc1 sec1 40
    region1 acc1 sec2 60
    region1 acc1 sec3 80
    region1 acc2 sec2 50
    region1 acc2 sec5 70
    region2 acc3 sec6 120
    6 rows selected.
    I get the following output for the below query.
    SELECT region, accname, secname, SUM (col1)
    FROM acc
    GROUP BY ROLLUP (region, accname, secname);
    REGION ACCNAME SECNAME SUM(COL1)
    region1 acc1 sec1 40
    region1 acc1 sec2 60
    region1 acc1 sec3 80
    region1 acc1 180
    region1 acc2 sec2 50
    region1 acc2 sec5 70
    region1 acc2 120
    region1 300
    region2 acc3 sec6 120
    region2 acc3 120
    region2 120
    420
    12 rows selected.
    I need customized heading like 'Security Total'/'Account Total'/'Regionwise Total' against grouped amounts. Is there anyway to get this. I am using Oracle 9i. Please help me.
    Thanks.

    We can throw in the GROUPING_ID function:
    select case grouping_id(deptno, job)
    when 0
    then 'No Subtotalling'
    when 1
    then 'Job Subtotal'
    when 2
    then 'Department Total'
    when 3
    then 'Grand Total'
    end
    , case grouping(deptno)
    when 1
    then 'Department Total'
    else to_char(deptno)
    end Department
    , case grouping(job)
    when 1
    then 'Job SubTotal'
    else job
    end Job
    , sum(sal) salary_sum
    from emp
    group
    by rollup (deptno, job)
    I am not exactly sure what you are looking for. However, using GROUPING_ID you can determine what columns you are sub-totaling on (or rolling up by) in a given record.
    If you are only interested in certain subtotals, you can use this query in an inline view that you further restrict.
    Results:
    CASEGROUPING_ID( DEPARTMENT JOB SALARY_SUM
    No Subtotalling 10 CLERK 1300
    No Subtotalling 10 MANAGER 2450
    No Subtotalling 10 PRESIDENT 5000
    Job Subtotal 10 Job SubTotal 8750
    No Subtotalling 20 CLERK 1900
    No Subtotalling 20 ANALYST 6000
    No Subtotalling 20 MANAGER 2975
    Job Subtotal 20 Job SubTotal 10875
    No Subtotalling 30 CLERK 950
    No Subtotalling 30 MANAGER 2850
    No Subtotalling 30 SALESMAN 5600
    Job Subtotal 30 Job SubTotal 9400
    Grand Total Department Total Job SubTotal 29025
    Lucas

  • Rank only summary rows from group by rollup

    I would like to rank only the total rows generated by a group by rollup, but not rank the rows within each group by bucket. Furthermore, I'd like to order by rank in descending order and include the unranked rows within each group.
    My query looks something like this:
    select customer, month, sum (sell)
    from sales
    group by rollup (customer, month)
    order by customer, month desc nulls first
    The results look like:
    customer     month     sum(sell)
    <summary rowA>          1,200
    custA          JAN     100
    custA          FEB     100
    custA          MAR     100
    custA          DEC     100
    <summary rowB>          600
    custB          JAN     50
    custB          FEB     50
    custB          MAR     50
    custB          DEC     50
    What I would like to do is:
    select dense_rank() over (order by sum(sell) desc <rollup rows only>) as rank,
         customer, month, sum (sell)
    from sales
    group by rollup (customer, month)
    order by <summary row rank desc> customer, month desc nulls first
    The results would look like:
    rank     customer     month     sum(sell)
    1     <summary rowA>          1,200
         custA          JAN     100
         custA          FEB     100
         custA          MAR     100
         custA          DEC     100
    2     <summary rowB>          600
         custB          JAN     50
         custB          FEB     50
         custB          MAR     50
         custB          DEC     50
    Any advice?
    Thank you

    Like this?
    sql>
    select decode(job,null,decode(deptno,null,null,dense_rank() over(order by lst desc)-1),null) rank,
           deptno,job,sm
    from(
          select deptno,job,sm,last_value(sm) over(partition by deptno order by null ) lst
          from (
                select deptno,job,sum(sal) sm
                from emp
                group by rollup(deptno,job)));
    RANK DEPTNO JOB SM
                       29025 
       20  CLERK  1900 
       20  MANAGER  2975 
    1  20     10875 
       20  ANALYST  6000 
       30  CLERK  950 
       30  MANAGER  2850 
    2  30     9400 
       30  SALESMAN  5600 
       10  CLERK  1300 
       10  MANAGER  2450 
       10  PRESIDENT  5000 
    3  10     8750                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

  • 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

  • [10g] Need help with order by clause in hierarchical query

    I have the following sample data:
    CREATE TABLE     bill_test1
    (     parent_part     CHAR(25)
    ,     child_part     CHAR(25)
    ,     line_nbr     NUMBER(5)
    ,     qty_per          NUMBER(9,5)
    INSERT INTO bill_test1 VALUES ('ABC-1','ABC-10',100,1);
    INSERT INTO bill_test1 VALUES ('ABC-1','ABC-20',200,2);
    INSERT INTO bill_test1 VALUES ('ABC-1','ABC-30',300,3);
    INSERT INTO bill_test1 VALUES ('ABC-1','HARDWARE-1',401,10);
    INSERT INTO bill_test1 VALUES ('ABC-1','HARDWARE-2',402,5);
    INSERT INTO bill_test1 VALUES ('ABC-10','ABC-155',100,2);
    INSERT INTO bill_test1 VALUES ('ABC-10','HARDWARE-1',200,1);
    INSERT INTO bill_test1 VALUES ('ABC-155','RAW-2',100,4.8);
    INSERT INTO bill_test1 VALUES ('ABC-155','HARDWARE-3',200,3);
    INSERT INTO bill_test1 VALUES ('ABC-20','RAW-1',100,10.2);
    INSERT INTO bill_test1 VALUES ('ABC-30','RAW-3',100,3);And the query below gives me exactly what I want, in the order I want it. However, I am wondering if there is a way to get this order without creating the SEQ column, since I don't need it in my results
    SELECT     part_nbr
    ,     parent_part
    ,     child_part
    FROM     (
         SELECT     CONNECT_BY_ROOT b.parent_part                         AS part_nbr
         ,     b.parent_part
         ,     b.child_part
         ,     SYS_CONNECT_BY_PATH(b.line_nbr,' ')                    AS seq
         FROM     bill_test1 b
         ,     dual
         CONNECT BY     parent_part     = PRIOR child_part
    WHERE          part_nbr     = 'ABC-1'
    ORDER BY     seq
    Results of above query, except with SEQ included in SELECT (just to show what I'm sorting off of):
    PART_NBR                     PARENT_PART                  CHILD_PART                   SEQ
    ABC-1                        ABC-1                        ABC-10                        100
    ABC-1                        ABC-10                       ABC-155                       100 100
    ABC-1                        ABC-155                      RAW-2                         100 100 100
    ABC-1                        ABC-155                      HARDWARE-3                    100 100 200
    ABC-1                        ABC-10                       HARDWARE-1                    100 200
    ABC-1                        ABC-1                        ABC-20                        200
    ABC-1                        ABC-20                       RAW-1                         200 100
    ABC-1                        ABC-1                        ABC-30                        300
    ABC-1                        ABC-30                       RAW-3                         300 100
    ABC-1                        ABC-1                        HARDWARE-1                    401
    ABC-1                        ABC-1                        HARDWARE-2                    402

    Hi,
    As long as there's only one root, you can say ORDER SIBLINGS BY, but you can't do that in a sub-query (well, you can, but usually there's no point in doing it in a sub-query). If the CONNECT BY is being done in a sub-query, there is no guarantee that the main query will preserve the hierarchical order that the sub-query provides.
    The query you posted doesn't require a suib-query, so you can say:
    SELECT     CONNECT_BY_ROOT b.parent_part                         AS part_nbr
    ,     b.parent_part
    ,     b.child_part
    --,     SYS_CONNECT_BY_PATH(b.line_nbr,' ')                    AS seq
    FROM     bill_test1 b
    WHERE          CONNECT_BY_ROOT b.parent_part     = 'ABC-1'
    CONNECT BY     parent_part     = PRIOR child_part
    ORDER SIBLINGS BY     b.line_nbr     
    ;I said the query you posted doesn't require a sub-query. It also doesn't require dual, so I suspect what you posted is a simplification of what you're really doing, and that may need a sub-query. In particular, if you intend to GROUP BY part_nbr, then you need the sub-query. We can repeat the CONNECT_BY_ROOT expression in the WHERE clause (or, now that I think about it, use a START WITH clause instead of WHERE), but, for some reason, we can't use CONNECT_BY_ROOT in a GROUP BY clause; we need to compute CONNECT_BY_ROOT in a sub-query, give it a name (like part_nbr), and GROUP BY that column in a super-query.
    This assumes that there is only one root node. ORDER SIBLINGS BY means just that: children of a common parent will appear in order, but the root nodes, who have no parents, will not necessarily be in order.
    Here's what I meant by using START WITH instead of WHERE:
    SELECT     CONNECT_BY_ROOT b.parent_part                         AS part_nbr
    ,     b.parent_part
    ,     b.child_part
    --,     SYS_CONNECT_BY_PATH(b.line_nbr,' ')                    AS seq
    FROM     bill_test1 b
    START WITH     b.parent_part     = 'ABC-1'
    CONNECT BY     parent_part     = PRIOR child_part
    ORDER SIBLINGS BY     b.line_nbr     
    ;This should be much more efficient, because it narrows down the results before you waste time getting their descendants.
    Using a START WITH clause here is analagous to me sending you an e-mail, saying "Come to a meeting a my office at 3:00."
    Using a WHERE clause here is analagous to me sending an e-mail to everyone in the company, saying "Come to a meeting a my office at 3:00", and then, as people get here, telling everyone except you that they can go back.
    ORDER SIBLINGS BY was introduced in Oracle 9.
    Edited by: Frank Kulash on Dec 9, 2010 2:39 PM
    Added version with START WITH clause

  • Problem with Hierarchical query

    Gurus,
    I have a problem with hierarchical query, which I am pasting below.
    select sys_connect_by_path (Fname,'/')"PATH",Fname,id,level
    ,(SELECT COUNT(ID)-1 FROM (SELECT CONNECT_BY_ROOT LNAME LNAME,ID FROM CMT_PERSON
    START WITH ID = 'emplo000000000126009'
    CONNECT BY PRIOR ID=MANAGER_ID)
    GROUP BY FNAME)"COUNT"
    from CMT_PERSON
    WHERE
    LEVEL <= 4
    ----And ID='emplo000000000001877'
    CONNECT BY PRIOR id=manager_id
    ----AND NOT LEVEL > 3
    START WITH ID='emplo000000000126009'
    As per the result, count is getting repeated for all the levels. That is, count is coming 16100 for every level, Can you please help where exactly I am going wrong
    Regards

    You do not say anything about what count you want to get?
    A wild guess could be:
    select
       sys_connect_by_path (p1.fname, '/') "PATH",
       p1.fname,
       p1.id,
       level,
       (select count (id) - 1
        from
           (select connect_by_root p2.lname lname, p2.id
            from cmt_person p2
            start with p2.id = p1.id
            connect by prior p2.id = p2.manager_id)
        ) "COUNT"
    from cmt_person p1
    where level <= 4
    connect by prior p1.id = p1.manager_id
    start with p1.id = 'emplo000000000126009';Since your inner query simply starts with the hardcoded employee id, naturally it will give you the same count.
    My guess is your inner query should start with the person id from the outer query?
    If that is not the case - please state in plain english what you are trying to accomplish ;-)
    (Oh, and please paste code within tags so we can read it more easily...)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Hierarchical query with where clause

    Hi,
    How can I query hierarchically a query with WHERE clause? I have a table with three fields session_id,id and root_id.
    When I try with the following query,
    select id, level from relation
    where session_id = 79977
    connect by prior id = root_id start with id = 5042;
    It gets duplicate values.
    I want the query to show in the hierarchical manner with a filter condition using WHERE clause. Please help me how can I achieve this. If you know any link that describes more about this, please send it.
    Thanks in Advance.
    Regards,
    -Parmy

    Hi Sridhar Murthy an others,
    Thanks a lot for your/the answer. It's working for me. It saved a lot of other work around without the proper knowledge of hierarchical query. Please send me any link that describes these issues in detail and also I hope as I have mentioned in the other message, same cannot be achieved on views or ( on two different tables ???)
    Any way thanks for your reply,
    It's working for me.
    With happiness,
    -Parmy

  • Problem with different execution paths in hierarchical query

    Hello,
    I have problems with the following query:
    SELECT DISTINCT P.ID FROM PRODUCTELEMENTIMPL P WHERE ( ( LABEL = 'SomeLabel' AND PRODUCTELEMENTTYPE = 'SomeText' AND ( STATE = 'created' OR STATE = 'stored' OR STATE = 'archived' OR STATE = 'archivedRestored' ) ) ) START WITH P.ID = 42 CONNECT BY PRIOR P.ID = P.PARENT
    We have two databases (an Oracle 10g XE and Oracle10g Enterprise). In the XE Database the query is executed very fast, but in the main installation it takes minutes. If I "explain" the query I get two different execution paths:
    The fast:
    ID      PARENT_ID      LEVEL      SQL      Kosten      Anzahl Zeilen
    0      -      1      SELECT STATEMENT      20      49
    1      0      2      HASH UNIQUE      20      49
    2      1      3      FILTER      -      -
    3      2      4      CONNECT BY WITH FILTERING      -      -
    4      3      5      TABLE ACCESS BY INDEX ROWID PRODUCTELEMENTIMPL (TABLE)      -      -
    5      4      6      INDEX UNIQUE SCAN SYS_C0072201 (INDEX (UNIQUE))      2      1
    6      3      5      NESTED LOOPS      -      -
    7      6      6      BUFFER SORT      -      -
    8      7      7      CONNECT BY PUMP      -      -
    9      6      6      TABLE ACCESS BY INDEX ROWID PRODUCTELEMENTIMPL (TABLE)      19      49
    10      9      7      INDEX RANGE SCAN PRODUCTELEMENTIMPL_IDX1 (INDEX)      3      49
    11      3      5      TABLE ACCESS FULL PRODUCTELEMENTIMPL (TABLE)      19      49
    Slow:
    ID PARENT_ID LEVEL SQL Kosten Anzahl Zeilen
    0 1 SELECT STATEMENT 1 1
    1 0 2 HASH UNIQUE 1 1
    2 1 3 FILTER
    3 2 4 CONNECT BY WITHOUT FILTERING
    4 3 5 TABLE ACCESS BY INDEX ROW 3 1
    ID PRODUCTELEMENTIMPL (TABLE)
    5 4 6 INDEX UNIQUE SCAN SYS_C0 2 1
    020528 (INDEX (UNIQUE))
    6 3 5 TABLE ACCESS FULL PRODUCT 6628 1100613
    ELEMENTIMPL (TABLE)
    Any ideas how to avoid this full table scan?
    bye
    Roland Spatzenegger

    Hello,
    thank you for your replies. The indices and table schemas are the "same", but only the content for the tables was mirrored.
    We made some tests with dropping and/or analyzing the tables, but it didn't change anything.
    The main problem is that the query takes 33s in the productive environment for searching in a couple of rows. At the moment it's faster to make
    SELECT DISTINCT P.ID, P.STATE FROM PRODUCTELEMENTIMPL P WHERE ( ( LABEL = 'SomeLabel' AND PRODUCTELEMENTTYPE = 'SomeText' ) ) START WITH P.ID = 42 CONNECT BY PRIOR P.ID = P.PARENT
    and to test in the application if the state-values match ;-)
    If I add the hint /*+ no_filtering */ in the test environment, I get the same "slow" execution path as in the production environment. So the question is, what prevents the filtering in "connect by"?
    (I think in the fast version it filters only the results of the hierarchical query, in the slow version it first filters the whole table and joins/merge it with the hierachical result).
    bye
    Roland Spatzenegger

  • How to use order by with hierarchical query

    I have a hierarchical query basically it brings back an organization chart. We start with a manager's id, get all that person's employees. If any of the employees is also a manager I want to get that person's employees and return them right after that person. I won't bother with the whole query but relevant part is:
           START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id;Where pi_mgr_id is a parameter passed to the procedure and em is the alias for the emp_mgr_relationship table which contains emp_id and mgr_id. This works fine. What I want now is for the employees who work for the same manager to appear in name order. The table which contains the employee names is aliased as pe and the name column is called name1. I added the following:
           START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id
            order by pe.name1;But that put the entire list in name order. What I want is for employees who work for the same manager to be in name order. Let's the manager whose organization I want is named Frank. What I'd like to get is this
    EMP_NAME    MGR_NAME
    Allen       Frank
    Beth        Frank
    Alex        Beth
    Charles     Beth
    Ed          Beth
    Dean        Frank
    George      Frank
    Benny       George
    David       George
    Sam         George
    Dan         Sam
    Harry       Sam
    John        Sam
    Terry       George
    James       Frank
    Ken         Frank
    Mike        Ken
    Warren      KenHow do I get the list in this order?
    Edited by: kendenny on Jul 28, 2010 7:31 AM

    Make use of ORDER SIBLINGS clause in hierarchial queries to set the order by child columns.
    START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id
            *order siblings by name1;*

  • Problems with Views based on a Hierarchical Query

    Datamodeler 3.1.3.706 (SQL Dev 3.2.10.09):
    When creating a view that utilizes a Hierarchical Query, the Query Builder encounters various difficulties:
    When pasting in SQL code, if the view is saved without first clicking the update diagram button, the object in the view entity relationship diagram provides a faithful representation of the view without errors, but when reopening the view, the code is missing.
    Simple Example using the classic emp table:
    SELECT level lev
          , emp.*
       FROM emp
      CONNECT BY prior empno = mgr
      START WITH mgr        IS NULLIf the update diagram button is pushed to refresh the graphical view. It mangles the connect by clause and the view gets marked with a warning/error icon in the relationship diagram, but the now mangled code remains available on reopening the query builder.
    Same code as above after clicking the Update Diagram button:
    SELECT Level lev
    , emp.*
       FROM emp
      CONNECT BYFurther issues are encountered if the query contains any of the CONNECT_BY_% hierarchical pseudo columns:
    SELECT level
          , emp.*
          , connect_by_root emp.ename root_ename
       FROM emp
      CONNECT BY prior empno = mgr
      START WITH mgr        IS NULL;In this case pasting in the code and clicking either the Update Diagram button or the OK button results in an "Unexpected Token" parsing error.
    These issues are encountered with both the Logical and Relational models.
    Is this a known issue? I've searched this forum but haven't found any references to it.
    Thanks,
    Sentinel

    Hi Sentinel,
    I logged a bug for that.
    You can try DM 3.3 it deals better with first problem, parsing of connect_by_root operator will pass if you don't use alias.
    Philip

  • Query with GROUP BY ROLLUP

    I have a query :
    SELECT e.deptno,d.dname,e.job,SUM(e.sal)
    FROM emp e,dept d
    WHERE e.deptno = d.deptno
    GROUP BY ROLLUP(e.deptno,d.dname,e.job)
    which gives the output with Deptno and Dept Name repeated for every row, I want them to appear only once for each Dept Num.
    Can you folks help me out on this.
    Thanks and Regards,
    Gaurav Srivastava

    scott@ORA92> BREAK  ON deptno ON dname
    scott@ORA92> SELECT e.deptno, d.dname, e.job, SUM(e.sal)
      2  FROM   emp e, dept d
      3  WHERE  e.deptno = d.deptno
      4  GROUP  BY ROLLUP (e.deptno, d.dname, e.job)
      5  ORDER  BY e.deptno, d.dname, e.job
      6  /
        DEPTNO DNAME          JOB       SUM(E.SAL)
            10 ACCOUNTING     CLERK           1300
                              MANAGER         2450
                              PRESIDENT       5000
                                              8750
                                              8750
            20 RESEARCH       ANALYST         6000
                              CLERK           1900
                              MANAGER         2975
                                             10875
                                             10875
            30 SALES          CLERK            950
                              MANAGER         2850
                              SALESMAN        5600
                                              9400
                                              9400
                                             29025
    16 rows selected.

Maybe you are looking for

  • How To use barcode in the sap scripts

    I have to put two windows in a form ,both windows should contain BARCODE so how i can proceed plz provide me solutions for same and possible few example code which can guide me .

  • Problem in converting util date format to sql date format

    im trying to convert util date to sql date...i'm getting the error msg as Error is : java.lang.NullPointerException Error Message : null i'm not bale to track the result...whatz the problem with this code? This fromDate value will be dynamically buil

  • Setting ALV Column width

    Hi experts, I'm trying to set fixed width in my ALV report. I using set_width to set the fixed width. But I could not get the fixed width. data salv_column      type ref to cl_salv_wd_column. salv_column->set_width( '4' ). When I try this i'm getting

  • Ttrigger error

    Why the following code gives error ?? CREATE OR REPLACE TRIGGER log_new_salary AFTER UPDATE ON emp FOR EACH ROW WHEN (NEW.sal >1000) BEGIN INSERT INTO emp_log (emp_id, log_date, new_salary, action) VALUES (:NEW.empno, SYADATE, :NEW.sal, 'NEW SAL'); E

  • Help: there is a way to delete duplicate files in itune?

    every time when im importing music on my itunes is storing the files in the itunes music folder. now i have to backup this folder and the size is more than 80GB. i found that there are many duplications of songs. is there any easy way to delete dupli