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,
KamleshDear 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 MillerHere 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 youLike 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:
cthOn 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 402Hi,
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
RegardsYou 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,
-ParmyHi 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 SpatzeneggerHello,
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 AMMake 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,
SentinelHi 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 -
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 Srivastavascott@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
-
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
-
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