Hierarchial Queries
Consider the follwoing data set:
Parent Child_Low Child_High
10 200 300
250 400 600
500 700 800
I want the following result set:
10 250 500.
I used the folowing query:
'select rownum, level, parent, child_low, child_high
from 'TABLE_NAME'
connect by
and prior child_low <= parent
and prior child >= parent'.
It certainly does not work.
Can somebody give me some kind a solution??????
check out the following query...
Select level,Parent ,Child_Low ,Child_high
from 'table_name'
start with Parent =10
connect by Parent between prior Child_low and prior child_high
Similar Messages
-
Top n analysis using hierarchial queries
hi all,
can we do top n analysis in hierarchial queries using level pseudo columns. if so please give an example.
thanks and regards,
sri ram.Hi,
Analytic functions (such as RANK) often interfere with CONNECT BY queries. Do one of them in a sub-query, and the other in a super-query, as shown below.
If you do the CONNECT BY first, use ROWNUM (which is assigned after ORDER SIBLINGS BY is applied) to preserve the order of the CONNECT BY query.
WITH connect_by_results AS
SELECT LPAD ( ' '
, 3 * (LEVEL - 1)
) || ename AS iname
, sal
, ROWNUM AS r_num
FROM scott.emp
START WITH mgr IS NULL
CONNECT BY mgr = PRIOR empno
ORDER SIBLINGS BY ename
SELECT iname
, sal
, RANK () OVER (ORDER BY sal DESC) AS sal_rank
FROM connect_by_results
ORDER BY r_num
;Output:
INAME SAL SAL_RANK
KING 5000 1
BLAKE 2850 5
ALLEN 1600 7
JAMES 950 13
MARTIN 1250 10
TURNER 1500 8
WARD 1250 10
CLARK 2450 6
MILLER 1300 9
JONES 2975 4
FORD 3000 2
SMITH 800 14
SCOTT 3000 2
ADAMS 1100 12
I hope this answers your question.
If not, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only), and the results you want from that data. If you use only commonly available tables (such as those in the scott or hr schemas), then you don't have to post any sample data; just post the results.
Explain how you get those results from that data.
Always say what version of oracle you're using. -
What is the role of PRIOR in hierarchial queries
hi all,
what is the role of prior operator in CONNECT BY Clause of the hierarchial queries, what is the effect when it is used on the right side or left side of the condition ? almost all the queries contains this clause, if it is omitted the child values are not coming. what is the reason. plz explain.
please check the following outputs:
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by empno = mgr;
ENAME HIERARCHY
KING \KING
Elapsed: 00:00:00.04
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by prior empno = mgr;
ENAME HIERARCHY
KING \KING
JONES \KING\JONES
SCOTT \KING\JONES\SCOTT
ADAMS \KING\JONES\SCOTT\ADAMS
FORD \KING\JONES\FORD
SMITH \KING\JONES\FORD\SMITH
BLAKE \KING\BLAKE
ALLEN \KING\BLAKE\ALLEN
WARD \KING\BLAKE\WARD
MARTIN \KING\BLAKE\MARTIN
TURNER \KING\BLAKE\TURNER
JAMES \KING\BLAKE\JAMES
CLARK \KING\CLARK
MILLER \KING\CLARK\MILLER
14 rows selected.
Elapsed: 00:00:00.09
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by empno = prior mgr;
ENAME HIERARCHY
KING \KING
Elapsed: 00:00:00.06
SQL>
thanks and regards,
sri ram.Hi, Sri Ram,
Sri Ram wrote:
hi all,
what is the role of prior operator in CONNECT BY Clause of the hierarchial queries, "PRIOR x" means a value of x from one of the rows that were added to the result set at the previous level.
what is the effect when it is used on the right side or left side of the condition ? There is no difference between
CONNECT BY PRIOR x = yand
CONNECT BY y = PRIOR xjust like there is no difference between
WHERE x = yand
WHERE y = x
almost all the queries contains this clause, No, most queries do not contain a CONNECT BY clause.
Most queries that have a CONNECT BY clause do use a PRIOR operator.
if it is omitted the child values are not coming. what is the reason. plz explain.No, that's not true. A common example is a Counter Table :
SELECT SYSDATE + LEVEL - 1
FROM dual
CONNECT BY LEVEL <= 7;
please check the following outputs:
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by empno = mgr;
ENAME HIERARCHY
KING \KING
Elapsed: 00:00:00.04
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by prior empno = mgr;
ENAME HIERARCHY
KING \KING
JONES \KING\JONES
SCOTT \KING\JONES\SCOTT
ADAMS \KING\JONES\SCOTT\ADAMS
FORD \KING\JONES\FORD
SMITH \KING\JONES\FORD\SMITH
BLAKE \KING\BLAKE
ALLEN \KING\BLAKE\ALLEN
WARD \KING\BLAKE\WARD
MARTIN \KING\BLAKE\MARTIN
TURNER \KING\BLAKE\TURNER
JAMES \KING\BLAKE\JAMES
CLARK \KING\CLARK
MILLER \KING\CLARK\MILLER
14 rows selected.
Elapsed: 00:00:00.09
SQL> select ename,sys_connect_by_path(ename,'\') hierarchy from emp start with ename='KING' connect by empno = prior mgr;
ENAME HIERARCHY
KING \KINGOkay, I checked them. I get the same results. Did you have a question about them? -
Doubt's regarding the Hierarchial Queries in Oracle
Hi,
i have a doubt regarding the Hierarchial Queries in Oracle.
SELECT * FROM TMP_TEST;
ID NUMVAL STRVAL
1 100 Hello
1 -100 World
2 1 Concatenate
2 2 In String
2 3 using Connect By
2 4 Using SYS_CONNECT_BY_PATH
i am clear with my execution of IN_Line view (mechanism how it work's) .
But i have also read about the Hierarchial queries in the Oracle product documentation's. i am also aware of the
SYS_CONNECT_BY_PATH , LEVEL & START WITH , CONNECT BY Keywords.
But i couldnot able to Manually work out as how this below Query works.
Can you please explain me how this Hieracial query works ?
SELECT ID, (SYS_CONNECT_BY_PATH(STRVAL,',')),LEVEL
FROM
SELECT ID,STRVAL,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) RNUM,
COUNT(*) OVER(PARTITION BY ID ORDER BY ID) CNT,NUMVAL
FROM TMP_TEST
START WITH RNUM = 1
CONNECT BY PRIOR RNUM = RNUM - 1
Many Thanks,
Rajesh.Hi, Rajesh,
My first message was in response to your first message.
In your latest message, the query is:
SELECT ID, (SYS_CONNECT_BY_PATH(STRVAL,',')),LEVEL
FROM (
SELECT ID,STRVAL,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) RNUM,
COUNT(*) OVER(PARTITION BY ID ORDER BY ID) CNT,NUMVAL
FROM TMP_TEST
WHERE RNUM = CNT
START WITH RNUM = 1
CONNECT BY PRIOR RNUM = RNUM - 1;It looks like you lost the second CONNECT BY condition:
AND PRIOR ID = IDPut it back: it's important.
Now you're confused about the output row:
2 ,Hello,World,using Connect By,Using SYS_CONNECT_BY_PATH 4It doesn't seem to correspond to anything results that you got when you ran the sub-query alone.
That's because the resutls from your sub-query may change every time you run it, even though the data doesn't change. The ORDER BY clauses in both of the analytic functions do not result in a complete ordering. In fact, they're completely meaningless. It never makes any sense to PARTITON BY and ORDER BY the same value; "PARTITION BY id" means that only rows with the same id will be compared to each other; you might as well say "ORDER BY 0" or "ORDER BY dmbs_random.value".
The ORDER BY clause of ROW_NUMBER whould reflect that way in which you want the results to appear within each id, for example:
ROW_NUMBER () OVER (PARTITION BY id ORDER BY UPPER (strval))Note that this is very similar to what was in my first reply.
In the COUNT function, why do you want an ORDER BY clause at all? Just say:
COUNT (*) OVER (PARTITION BY id) -
Please answer the below queries on urgent manner
Scenario 1. SCCM installed as a primary stand alone site, It is possible to install/configure another primary site in same site code.
I understand existing stand alone should connected to CAS server first, Under the CAS server can i install another Primary site in remote locations - ??
Scenarion 2. Assume i installed CAS server first, created the primary(1st) in Headoffice and plannned to install another primary (2nd) site in remote location. Any replication will happen be between CAS server and primary site (2nd) installed in
remote locations. If Yes, can it scheduled at off time or it can enabled with Branch cache. -??If I continue with my stand alone primary site, is it possible to extend another primary site under existing primary site server
without introducing CAS server ??<o:p></o:p>
Rajesh – No, it is not possible,<o:p></o:p>
If its allowed to introduce another primary site under existing stand alone primary site, Whether the new primary
site can handle clients independently (No client should contact parent primary site) ??<o:p></o:p>
Rajesh :: This scenario is not possible. <o:p></o:p>
If i planned to introduce secondary site under existing stand alone primary site, Separate CAS server still
required ??.<o:p></o:p>
Rajesh :: No it is not required. You can install a secondary Site under the primary site without the CAS.<o:p></o:p>
If i add an secondary site under exisitng primary site server, i assumed secondary site server data's (client
info) will always replicate to primary site - this will choke my network traffic -??<o:p></o:p>
Rajesh :: Secondary Site will always replicate the data to Primary Site. Bandwidth utilization depends on the number of clients
on the secondary site. If you have less than 2000 clients and have a good network link, you can still survive with a DP only.<o:p></o:p>
Assume, I installed CAS server, Under CAS server two primary server (1 - HO site, 1 - Branch site) added.
In that case i need clarity, whether branch primary site will replicate continously with CAS server for data replication ??<o:p></o:p>
Rajesh :: Yes, There will be a continuous data replication between CAS and Primary site. In addition to that content and un
processed DDRs will flow using file base replication. However you can configure bandwidth throttling using replication routes to control file base replication. Please visit following link to understand data replication in SCCM 2012.
http://blogs.technet.com/b/server-cloud/archive/2012/03/06/data-replication-in-system-center-2012-configuration-manager.aspx -
Hierarchial Queries and Redo log files
Hi,
I'm running a hierarchial query (start with, connect by prior, etc.).
The query takes a couple of minutes and apparently is filling up the archive files
(I assume it comes from the redo log files).
Question:
1. Does it make sense that a hierarchial query should so fill up the redo log files (It seems as if all the 'intermediate' results are being written there).
2. What do you suggest I do ??
Thanks,
DavidWhat do you suggest I do ??Post your query and the execution plan or the trace file from tkprof.
How to do that is explained in this thread;
How to post a SQL statement tuning request HOW TO: Post a SQL statement tuning request - template posting -
Chanllenging task in hierarchial queries
I have a table sk_main
create table sk_main(empno number, mgr number)
insert into sk_main values (1,null);
insert into sk_main values (2,1);
insert into sk_main values (3,1);
insert into sk_main values (4,2);
insert into sk_main values (6,2);
insert into sk_main values (5,3);
Another Table
create table sk_recalc(id number, tag_val varchar2(1000))
Initially table is loaded like this,
insert into sk_recalc
select rownum,ltrim(sys_connect_by_path(empno,'\'),'\') from sk_main
start with mgr is null
connect by prior empno=mgr;
Output1:
ID|TAG_VAL
1|1
2|1\2
3|1\2\4
4|1\2\6
5|1\3
6|1\3\5
Now assume below DML's Happened to sk_main table,
insert into sk_main values(7,2);
update sk_main set mgr=7 where empno=4
so now tag_val's become
Output2:
ROWNUM|LTRIM(SYS_CONNECT_BY_PATH(EMPNO,'\'),'\')
1|1
2|1\2
3|1\2\6
4|1\2\7
5|1\2\7\4
6|1\3
7|1\3\5
now if we see output1 and output2,
sk_recalc() output is below before dml operations to sk_main table, after dml operations, sk_recalc() table should get update for those records which are different
Output1:
ID|TAG_VAL
1|1
2|1\2
3|1\2\4
4|1\2\6
5|1\3
6|1\3\5
and after dml operations sk_recalc() table should get update for those records which are different after dml operations, for example
1,1\2,1\2\6,1\3,1\3\5 are same before and after dml operations so this id's should not change in sk_recalc table,
1\2\4 will become 1\2\7 and 1\2\7\4 comparing this 1\2\4 is substring of 1\2\7\4 so 1\2\7\4 will be updated with id of 1\2\4 in the table and 1\2\7 will be inserted as new one,
and finally output should look like:
Required Output
ID|TAG_VAL
1|1
2|1\2
*3|1\2\7\4*
4|1\2\6
5|1\3
6|1\3\5
*7|1\2\4*
Thanks for your help in advance,MERGE INTO sk_recalc s
USING
(select rownum id,ltrim(sys_connect_by_path(empno,'\'),'\') tag_val from sk_main
start with mgr is null
connect by prior empno=mgr) t
ON (s.id = t.id)
WHEN MATCHED THEN
update set tag_val = t.tag_val
WHEN NOT MATCHED THEN
insert values ( t.id,t.tag_val); -
Where-used list for queries restricted by characteristic value
Hi SDN Community
I came across this useful documentation on how to track down a query which is restricted to a certain hierarchy
Queries that use a hierarchy
Is it possible to track down queries from a given characteristic value.
eg. ID = 355 from InfoObject ZIDMEASP, represents Production Measure ID.
Thank you.
SimonHi SDN community,
So far i have had this response from SAP OSS Message but require this as a consulting issue.
Is it such that anyone is aware of the way to tract down queries from restricted value,
Thank you.
25.10.2007 - 10:54:51 CET SAP Reply
Dear Simon,
You can track down the query from a characteristic as per the following
steps, eg.
- Tr_cd: RSD1
- eg. input ZIDMEASP to Infoobject
- click on "Where-used list using AWB"
- find out which InfoCube, InfoSet, ODS Object etc. are using
infoobject ZIDMEASP
- open bex analyzer, in the "Select query" screen, search with the
InfoCube/InfoSet/ODS Object one by one under "InfoAreas", then you
can see which query is using them -
Hierarchy Query - Removing Child Nodes
Hopefully an easy one for someone practiced with hierarchy queries.
If I have a hierarchy:
A
B
CThe where clause restricts the result so that B is removed, I now have:
A
CI would like to make it so that if you cut off a node, the entire branch beneath it is cut. In this example, only A should be returned.
My experience with hierarchy queries is limited, and I've searched high-and-low for an example or discussion to make this happen using a standard method. I'm sure I can make it happen, but if there is an established/standard (aka efficient) way of making this happen I'd prefer to do that. Everything I have found references making C show up...that's obviously not what I'm having a problem doing.
Here's an example:
CREATE TABLE Z_HIERARCHY (
test_id NUMBER,
label VARCHAR2(50),
parent_id NUMBER);
INSERT INTO Z_HIERARCHY VALUES (1, 'A', 0);
INSERT INTO Z_HIERARCHY VALUES (2, 'B', 1);
INSERT INTO Z_HIERARCHY VALUES (3, 'C', 2);
COMMIT;
SELECT label, level
FROM z_hierarchy
START WITH parent_id = 0
CONNECT BY PRIOR test_id = parent_id;
Result:
A
B
C
SELECT label, level
FROM z_hierarchy
WHERE test_id <> 2
START WITH parent_id = 0
CONNECT BY PRIOR test_id = parent_id;
Result:
A
CWhat I want is simply A. C is dependent on a parent that isn't in the result set...don't want it shown either.
Thanks in advance!
RonHi, Ron,
So you want to pretend, just for this query, that the row with test_id=2 doesn't exist? Then do what Tubby suggested: run the query, not on the full z_hierarchy table, but on a copy of the table where that row doesn't exist.
You could also do something like this:
SELECT label
, LEVEL
FROM z_hierarchy
START WITH parent_id = 0
CONNECT BY parent_id = PRIOR test_id
AND test_id != 2
;but, depending on your requirements, you might need to put a similar condition in the START WITH clause. In general, Tubby's solution is best.
rmhardma wrote:
... No other built-in way to do this without doing the inline view, eh?Sure: you can always replace an in-line view with a WITH clause:
WITH good_rows_only AS
select *
FROM z_hierarchy
WHERE test_id != 2
SELECT label, level
from good_rows_only
START WITH parent_id = 0
CONNECT BY PRIOR test_id = parent_id;Pehaps you meant "without a sub-query". -
Need to Store Infinite Tree in a single table
Hi,
I need to create infinite tree and also need to store it into a single table. I will perform operations like node deletion,movement etc.. according to the operation my tree should get updated.Can anyone please give me any suggestion??
Thanks in Advance,
Sumeet GuptaHi,
Not much to go on, but this table can hold an infinite tree. Work from that.
SQL> create table tree (node number(15) not null, parent_node number(15))
Table created.
SQL> alter table tree add constraint tree_pk primary key (node)
Table altered.
SQL> alter table tree add constraint tree_tree_fk foreign key (parent_node) references tree (node)
Table alteredEdit:
If you are not already familar with hierarchial queries, I suggest you look here:
[Hierarchial query|http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_10002.htm#sthref9434]
Regards
Peter
Edited by: Peter on Mar 3, 2009 7:35 AM -
Hi All,
Did anyone managed to parallelize CONNECT BY PUMP rowsource and its corresponding join?
I'm thinkging about following steps from execution plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
| 5 | NESTED LOOPS | | | | | | | |
| 6 | CONNECT BY PUMP | | | | | | | |
-------------------------------------------------------------------------------------------------------------------------- Update:
Not solution, but kind of workaround. Maybe someone will find it useful. You can improve performance of CONNECT BY operation on big datasets (milions of rows) by parallelizing source rowset, using NO_CONNECT_BY_FILTERING hint and accessing data with FTS. This way you're parallel HJ, which for me was eight to ten times faster than other methods. BTW, you'll need significant amount of PGA available for this process - I was using manual worarea policy for this.
SQL> ALTER SESSION SET workarea_size_policy=MANUAL;
Session altered.
Elapsed: 00:00:00.00
SQL> ALTER SESSION SET sort_area_size=1073741824;
Session altered.
Elapsed: 00:00:00.00
SQL> INSERT /*+ APPEND */ INTO zzz_t1 SELECT /*+ NO_CONNECT_BY_FILTERING */ * FROM cp1_client StART WITH client_parent_id = 1 CONNECT BY PRIOR client_id = client_parent_id;
1497838 rows created.
Elapsed: 00:00:40.04
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
| 0 | INSERT STATEMENT | | | | 2330 (100)| | | | | | |
| 1 | LOAD AS SELECT | | | | | | | | | | |
|* 2 | CONNECT BY NO FILTERING WITH START-WITH| | | | | | | | | | |
| 3 | PX COORDINATOR | | | | | | | | | | |
| 4 | PX SEND QC (RANDOM) | :TQ10000 | 1497K| 617M| 2330 (2)| 00:00:28 | | | Q1,00 | P->S | QC (RAND) |
| 5 | PX BLOCK ITERATOR | | 1497K| 617M| 2330 (2)| 00:00:28 | 1 | 16 | Q1,00 | PCWC | |
|* 6 | MAT_VIEW ACCESS FULL | CP1_CLIENT | 1497K| 617M| 2330 (2)| 00:00:28 | 1 | 16 | Q1,00 | PCWP | |
----------------------------------------------------------------------------------------------------------------------------------------------------Thanks,
Lukasz
Edited by: Łukasz Mastalerz on Mar 26, 2012 2:11 PMThis is new feature of Oracle 9i and above related with hierarchy queries.
Sometimes it leads to peroformance problems. You can use undocumented
parameter oldconnect_by_enabled to get rid of it and return to "old good 8i":
SQL> set autotrace traceonly expl
SQL> select object_id from nc_objects start with object_id = 100
2 connect by prior object_id = parent_id
3 /
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=15 Bytes=345)
1 0 CONNECT BY (WITH FILTERING)
2 1 NESTED LOOPS
3 2 INDEX (UNIQUE SCAN) OF 'XPKNC_OBJECTS' (UNIQUE) (Cost=
2 Card=1 Bytes=12)
4 2 TABLE ACCESS (BY USER ROWID) OF 'NC_OBJECTS'
5 1 NESTED LOOPS
6 5 BUFFER (SORT)
7 6 CONNECT BY PUMP
8 5 TABLE ACCESS (BY INDEX ROWID) OF 'NC_OBJECTS' (Cost=6
Card=15 Bytes=345)
9 8 INDEX (RANGE SCAN) OF 'XIF25NC_OBJECTS' (NON-UNIQUE)
(Cost=3 Card=15)
SQL> alter session set "_old_connect_by_enabled" = true;
Session altered.
SQL> select object_id from nc_objects start with object_id = 100
2 connect by prior object_id = parent_id
3 /
Execution Plan
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=6 Card=15 Bytes=345
1 0 CONNECT BY
2 1 INDEX (UNIQUE SCAN) OF 'XPKNC_OBJECTS' (UNIQUE) (Cost=2
Card=1 Bytes=12)
3 1 TABLE ACCESS (BY USER ROWID) OF 'NC_OBJECTS'
4 1 TABLE ACCESS (BY INDEX ROWID) OF 'NC_OBJECTS' (Cost=6 C
rd=15 Bytes=345)
5 4 INDEX (RANGE SCAN) OF 'XIF25NC_OBJECTS' (NON-UNIQUE)
Cost=3 Card=15)Rgds. -
Pure SQL to partition date-time occurrences into non-overlapping windows?
i've a question that so far, i've never been able to solve via a pure SQL option.
it's hard to explain in words, but it's something like this:
given a set of date-time, i would like to partition the data into non-overlapping windows of 30 minutes each.
the data is supposed to be partitioned into windows of 30 minutes, meaning when the data is within 30 minutes of the first occurrence, only the first occurrence will be returned. in the next second after the 30th minute, the record will be considered as the start of a new window and is also returned. so those data that occurs within the window period are suppressed. the first occurrence is not necessarily occurring on the 00th minute, so the window start will never be constant.
run the below query to look at the dummy data.
SELECT 'A' AS ID
, TRUNC(SYSDATE) + 7 / 24 + 1 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 50
UNION ALL
SELECT 'A' AS ID
, TRUNC(SYSDATE) + 9 / 24 + 8 / 1440 + 1 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 35
UNION ALL
SELECT 'B' AS ID
, TRUNC(SYSDATE) + 7 / 24 + 5 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 15this is supposed to be the output.
ID DATETIME
A 5/19/2010 07:00:00
A 5/19/2010 07:30:00
A 5/19/2010 09:08:00
A 5/19/2010 09:38:00
B 5/19/2010 07:00:00
B 5/19/2010 07:30:00
B 5/19/2010 08:00:00so far, i'm using a PL/SQL to pipe the records. but i would like to know if this is achievable via SQL or not.
i've tried looking at analytics, width_bucket, ntile and alll options i can think of, but i just can't solve this at all.hey Bob,
your answer is most definitely correct and does what i want. i've verified it again my data set and it returns the results as required!
you've definitely proven me wrong. i was always under the impression that this wasn't possible. thanks!
just a small note:
i need the windows to be binned by seconds, so have changed the numtodsinterval to raw numbers.
WITH t AS
(SELECT 'A' AS ID
, TRUNC(SYSDATE) +(6.75 / 24) AS datetime
FROM DUAL
UNION ALL
SELECT 'A' AS ID
, TRUNC(SYSDATE) +(6.75 / 24) AS datetime
FROM DUAL
UNION ALL
SELECT 'A' AS ID
, TRUNC(SYSDATE) + 7 / 24 + 1 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 50
UNION ALL
SELECT 'A' AS ID
, TRUNC(SYSDATE) + 9 / 24 + 8 / 1440 + 1 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 35
UNION ALL
SELECT 'B' AS ID
, TRUNC(SYSDATE) + 7 / 24 + 5 *(ROWNUM - 1) / 1440 AS datetime
FROM DUAL
CONNECT BY ROWNUM <= 15)
,a AS
(SELECT ID
,datetime
,LAG(datetime) OVER(PARTITION BY ID ORDER BY datetime) AS prevtime
,LAST_VALUE(datetime) OVER(PARTITION BY ID ORDER BY datetime RANGE BETWEEN CURRENT ROW AND 30 / 1440 + 1 / 86400 FOLLOWING) AS interval_end
FROM t)
,b AS
(SELECT ID
,datetime
,LEAD(datetime) OVER(PARTITION BY ID ORDER BY datetime) AS nexttime
FROM t)
,ab AS
(SELECT a.ID
,a.datetime
,a.prevtime
,a.interval_end
,b.datetime as b_datetime
,b.nexttime
FROM a JOIN b ON(a.ID = b.ID
AND a.interval_end = b.datetime)
SELECT ID
,datetime
FROM ab
START WITH prevtime IS NULL
CONNECT BY ID = PRIOR ID
AND datetime = PRIOR nexttime
ORDER BY ID
,datetime;this most definitely proves that i'm still not sure of how to use hierarchy queries.
Edited by: casey on May 20, 2010 11:20 AM -
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;* -
Hi
I have a table like this below
Prdid prdcode seqno
445566 201 1
445566 202 2
445566 203 3
445566 204 4
445566 205 5
445566 206 6
445566 207 7
445566 208 8
Now a new column prvprdcd will be added to that table, by updating the previous value of prdcode, like below
prdid prdcode prvprdcode seqno
445566 201 202 1
445566 202 203 2
445566 203 204 3
445566 204 205 4
445566 205 206 5
445566 206 207 6
445566 207 208 7
445566 208 8
I think this task can be done by taking the maximum seqno value of prdid and using a cursor updating the prvprdcode
but can you please suggest is there any other better way doing that, i think it can be done by using
LAG function or by using Hierarchial Queries, Can you guys please show some light on it.
Second thing is
whenever the Prdid upgrades to new Prdid, the present prdid value should be passed to prvprdcode.
prdid prdcode prv_prdcode seqno
445566 200 201 1
445566 201 202 2
445566 202 203 3
445566 203 204 4
445566 204 205 5
445566 205 206 6
445566 206 207 7
445566 207 208 8
445566 208 9
The first one is a one time change, but the second will be done by using jobs which will run on a daily basis
the prdid will be checked for any new values in a master table, if there is any change this table will be updated
can you please let me know how can this be done.oracle_for_dude wrote:
Hi it is achieved by lead function not by lag
SQL> with t as(select 445566 Prdid, 201 prdcode, 1 seqno from dual union all
2 select 445566, 202, 2 from dual union all
3 select 445566, 203, 3 from dual union all
4 select 445566, 204, 4 from dual union all
5 select 445566, 205, 5 from dual union all
6 select 445566, 206, 6 from dual union all
7 select 445566, 207, 7 from dual union all
8 select 445566, 208, 8 from dual)
9 select Prdid,prdcode,lead(prdcode) over(order by prdcode) new_prdcode,seqno from t;
PRDID PRDCODE NEW_PRDCODE SEQNO
445566 201 202 1
445566 202 203 2
445566 203 204 3
445566 204 205 4
445566 205 206 5
445566 206 207 6
445566 207 208 7
445566 208 8
8 rows selected.
Your code will fail if the PRDID Changes
SQL> select Prdid,prdcode,lead(prdcode) over(order by prdcode) new_prdcode,seqno
from prds
PRDID PRDCODE NEW_PRDCODE SEQNO
445567 201 201 1
445566 201 201 1
445568 201 202 1
445566 202 202 2
445567 202 203 2
445566 203 203 3
445568 203 203 3
445567 203 204 3
445566 204 204 4
445567 204 205 4
445568 205 205 5
445566 205 205 5
445567 205 206 5
445567 206 206 6
445566 206 206 6
445568 206 207 6
445566 207 207 7
445567 207 208 7
445566 208 208 8
445568 208 208 8
445567 208 210 8
445568 210 211 4
445568 211 212 2
445568 212 7
24 rows selected.It Should be
SQL> select Prdid,prdcode,lead(prdcode)
over(PARTITION BY PRDID order by SEQNO) new_prdcode,seqno
from prds
PRDID PRDCODE NEW_PRDCODE SEQNO
445566 201 202 1
445566 202 203 2
445566 203 204 3
445566 204 205 4
445566 205 206 5
445566 206 207 6
445566 207 208 7
445566 208 8
445567 201 202 1
445567 202 203 2
445567 203 204 3
445567 204 205 4
445567 205 206 5
445567 206 207 6
445567 207 208 7
445567 208 8
445568 201 211 1
445568 211 203 2
445568 203 210 3
445568 210 205 4
445568 205 206 5
445568 206 212 6
445568 212 208 7
445568 208 8
24 rows selected.SS -
Slow connect by prior ... start with subquery in 9i
Has anyone come across a performance problem (compared to 8i) when using hierarchical queries where the START WITH list is generated by a subquery? The culprit seems to be an extra visit to the subquery block as part of the CONNECT BY WITH FILTERING operation.
For example, take a simple tree structure:
CREATE TABLE tree
id NUMBER,
parentid NUMBER
CONSTRAINT tree_pk PRIMARY KEY (id)
...and a subquery - here just a table called sample with a subset of the ids from the tree table:
CREATE TABLE sample
id NUMBER,
CONSTRAINT sample_pk PRIMARY KEY (id)
...with which to drive the start points of the treewalk:
SELECT parentid, id, label
FROM tree
CONNECT BY PRIOR parentid = id
START WITH id IN
SELECT id FROM SAMPLE
With the tables populated and analyzed, I get this from 8i:
Execution Plan
.0......SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=19)
.1....0...CONNECT BY
.2....1.....NESTED LOOPS (Cost=1 Card=1280 Bytes=10240)
.3....2.......INDEX (FAST FULL SCAN) OF 'ID_PK' (UNIQUE) (Cost=1 Card=1280 Bytes=5120)
.4....2.......INDEX (UNIQUE SCAN) OF 'TREE_PK' (UNIQUE)
.5....1.....TABLE ACCESS (BY USER ROWID) OF 'TREE'
.6....1.....TABLE ACCESS (BY INDEX ROWID) OF 'TREE' (Cost=2 Card=1 Bytes=19)
.7....6.......INDEX (UNIQUE SCAN) OF 'TREE_PK' (UNIQUE) (Cost=1 Card=1)
Statistics
.....0..recursive calls
.....4..db block gets
.15687..consistent gets
....59..physical reads
.....0..redo size
223313..bytes sent via SQL*Net to client
.38276..bytes received via SQL*Net from client
...343..SQL*Net roundtrips to/from client
.....3..sorts (memory)
.....0..sorts (disk)
..5120..rows processed
and this is 9i:
Execution Plan
.0......SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=19)
.1....0...CONNECT BY (WITH FILTERING)
.2....1.....NESTED LOOPS
.3....2.......NESTED LOOPS (Cost=2 Card=1280 Bytes=10240)
.4....3.........INDEX (FAST FULL SCAN) OF 'ID_PK' (UNIQUE) (Cost=2 Card=1280 Bytes=5120)
.5....3.........INDEX (UNIQUE SCAN) OF 'TREE_PK' (UNIQUE)
.6....2.......TABLE ACCESS (BY USER ROWID) OF 'TREE'
.7....1.....NESTED LOOPS
.8....7.......BUFFER (SORT)
.9....8.........CONNECT BY PUMP
10....7.......TABLE ACCESS (BY INDEX ROWID) OF 'TREE' (Cost=2 Card=1 Bytes=19)
11...10.........INDEX (UNIQUE SCAN) OF 'TREE_PK' (UNIQUE) (Cost=1 Card=20480)
12....1.....INDEX (UNIQUE SCAN) OF 'SAMPLE_PK' (UNIQUE) (Cost=1 Card=1 Bytes=4)
Statistics
.....1..recursive calls
.....1..db block gets
.20525..consistent gets
....72..physical reads
...120..redo size
224681..bytes sent via SQL*Net to client
.38281..bytes received via SQL*Net from client
...343..SQL*Net roundtrips to/from client
.....9..sorts (memory)
.....0..sorts (disk)
..5120..rows processed
..so, about another 5000 logical reads, corresponding to the extra access of the sample table at the bottom of the query plan. So instead of just visiting the START WITH subquery once, to kick off the treewalk, I seem to be revisiting it for every row returned. Not too bad if that happens to be a unique index scan as here but that's not always the case.
I know I've got new options for re-writing this as a join under 9i, I'm just curious about those extra lookups and why they're necessary.
Cheers - AndrewThere is undocumented parameter in Oracle 9i "_old_connect_by_enabled"
which controls the behavoiur of hierarchy queries in 9i and above:
You can try to return to 8i behaviour using it:
SQL> SELECT parentid, id
2 FROM tree
3 CONNECT BY PRIOR parentid = id
4 START WITH id IN
5 (
6 SELECT id FROM SAMPLE
7 )
8 /
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=26)
1 0 CONNECT BY (WITH FILTERING)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'TREE' (TABLE)
3 2 NESTED LOOPS (Cost=2 Card=1 Bytes=26)
4 3 TABLE ACCESS (FULL) OF 'SAMPLE' (TABLE) (Cost=2 Card
=1 Bytes=13)
5 3 INDEX (UNIQUE SCAN) OF 'TREE_PK' (INDEX (UNIQUE)) (C
ost=0 Card=1 Bytes=13)
6 1 NESTED LOOPS
7 6 BUFFER (SORT)
8 7 CONNECT BY PUMP
9 6 TABLE ACCESS (BY INDEX ROWID) OF 'TREE' (TABLE) (Cost=
1 Card=1 Bytes=26)
10 9 INDEX (UNIQUE SCAN) OF 'TREE_PK' (INDEX (UNIQUE)) (C
ost=1 Card=1)
11 1 TABLE ACCESS (FULL) OF 'TREE' (TABLE) (Cost=1 Card=1 Byt
es=26)
12 1 INDEX (UNIQUE SCAN) OF 'SAMPLE_PK' (INDEX (UNIQUE)) (Cos
t=1 Card=1 Bytes=13)
SQL> alter session set "_old_connect_by_enabled" = TRUE;
Session altered.
SQL> SELECT parentid, id
2 FROM tree
3 CONNECT BY PRIOR parentid = id
4 START WITH id IN
5 (
6 SELECT id FROM SAMPLE
7 )
8 /
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=26)
1 0 CONNECT BY
2 1 NESTED LOOPS (Cost=2 Card=1 Bytes=26)
3 2 TABLE ACCESS (FULL) OF 'SAMPLE' (TABLE) (Cost=2 Card=1
Bytes=13)
4 2 INDEX (UNIQUE SCAN) OF 'TREE_PK' (INDEX (UNIQUE)) (Cos
t=0 Card=1 Bytes=13)
5 1 TABLE ACCESS (BY USER ROWID) OF 'TREE' (TABLE)
6 1 TABLE ACCESS (BY INDEX ROWID) OF 'TREE' (TABLE) (Cost=1
Card=1 Bytes=26)
7 6 INDEX (UNIQUE SCAN) OF 'TREE_PK' (INDEX (UNIQUE)) (Cos
t=1 Card=1)
Rgds.
Maybe you are looking for
-
Hi I am having trouble getting certain programs to work through a LAN. I am connected to my friends Mac Pro via an ethernet cable and he is then connected to the modem. Through this connection it will allow me to access the internet through safari ho
-
When I watch NTSC mpeg2 movies on my MAC i am getting horrizontal lines through the picture. The Mpeg looks fine on a TV, but when watching it in DVDSP and on other computer monitors the lines appear. Can anybody tell me why and how to remove them?
-
Incomplete hierarchy in bex query (infoobject 0COSTCENTER)
Hi Friends! I have a problem with hierarchy on infoobject 0COSTCENTER, the hierarchy is completely loaded into BW system (and is active), but when displays in query bex, cost centers are missing in the hierarchy (nodes and cost centers). Plaese some
-
Is it possible to invoke an async process as you can in BPEL and wait for a response as in BPEL. I have an async process that may run for 30 mins, this is too long for a sync process so i want to call it asynchronously and wait for the response. When
-
Problem with downloading from itunes
I can log on to the Apple website to manage my account and all the information is correct, but I get "Your Apple ID has been disabled" when I try to get something from App Store. what is the problem ?