Hierarchical queries
Hello
I'm on Oracle 11 g 2. I have a table with child data parent with some documents are not not all data
for example
sequence of PEM Manager
John 100
200-mark
Mark Smith 300
Steve Smith 400
Carol marks 500
Nancy 600
I would like to get a result as below:
Manager emp has_child
John N
Mark Y
Mark Smith Y
N Steve Smith
Carol brand N
N Nancy
Here, I would like to preserve the order of the sequence-based data. Can someone please advise?
Thank you.
As said Tubby, a lot of options, here's another:
SQL > with t as)
2. Select 'John' emp, Manager null, seq 100 of all the double union
3. Select 'Bookmark', null, 200 Union double all the
4. Select 'Smith', 'Brand', 300 double Union all
5. Select 'Steve', 'Smith', 400 double Union all
6. Select 'Carol', 'Brand', 500 double Union all
7. Select 'Nancy', null, 600 double)
8. Select case connect_by_isleaf when 1 then ' else n 'Y' end has_child.
9 emp, Manager, seq
10 t
starting with the Manager 11 is null
12 connect by prior emp = manager
13 order to seq;
H EMP MANAG SEQ
- ----- ----- ----------
John N 100
Scored 200
Mark Smith Y 300
Steve Smith 400 N
Carol brand N 500
Nancy N 600
John
Tags: Database
Similar Questions
-
Hierarchical queries - problem with condition "begins by".
Hi people
I play with the connection by and start with clause and am faced with a particular problem which I can not solve...
My data set is:
Create table dates_q (start_date date, end_date date) /
REM INSERTING into dates_q Insert into dates_q ("START_DATE","END_DATE") values (to_date('01-JAN-14','DD-MON-RR'),to_date('10-JAN-14','DD-MON-RR')); Insert into dates_q ("START_DATE","END_DATE") values (to_date('11-JAN-14','DD-MON-RR'),to_date('20-JAN-14','DD-MON-RR')); Insert into dates_q ("START_DATE","END_DATE") values (to_date('10-MAR-14','DD-MON-RR'),to_date('20-MAR-14','DD-MON-RR')); Insert into dates_q ("START_DATE","END_DATE") values (to_date('21-MAR-14','DD-MON-RR'),to_date('31-MAR-14','DD-MON-RR')); Insert into dates_q ("START_DATE","END_DATE") values (to_date('01-APR-14','DD-MON-RR'),to_date('10-APR-14','DD-MON-RR'));
Now I basically just want to get your hands on hierarchical queries and working with the syntax of various...
What I now want is, start with the date of April 1 as my start date and work backward to build my 'tree '. The condition of my tree is between two rows; my start and end dates differ from 1 day. If they do not; I don't want these records in my tree.
And using sys_connect_by_path, I want to get all the way from the root.
Thus, for example,.
SELECT a.*, sys_connect_by_path(start_date, '|'), LEVEL lvl FROM dates_q a CONNECT BY PRIOR end_date = (start_date - 1)
I get the following output
START_DATE END_DATE SYS_CONNECT_BY_PATH(START_DATE,'|') LVL 01.01.2014 10.01.2014 | 1 JANUARY 14 1 11.01.2014 20.01.2014 | 1 JANUARY 14 | JANUARY 11, 14 2 11.01.2014 20.01.2014 | JANUARY 11, 14 1 10.03.2014 20.03.2014 | MARCH 10, 14 1 21.03.2014 31.03.2014 | MARCH 10, 14. MARCH 21, 14 2 01.04.2014 10.04.2014 |10-MAR-14|21-MAR-14|01-APR-14 3 21.03.2014 31.03.2014 | MARCH 21, 14 1 01.04.2014 10.04.2014 | MARCH 21, 14. 1 APRIL 14 2 01.04.2014 10.04.2014 | 1 APRIL 14 1 But for the moment I did not have any starting point... Now comes the FUN part...
When I give the State of departure; I get a single row :-(
Example of
SELECT a.*, sys_connect_by_path(start_date, '|'), LEVEL lvl FROM dates_q a CONNECT BY PRIOR end_date = (start_date - 1) START WITH start_date = To_Date('01-apr-2014','dd-mon-yyyy');
The result is
START_DATE END_DATE SYS_CONNECT_BY_PATH(START_DATE,'|') LVL 01.04.2014 10.04.2014 | 1 APRIL 14 1 Just a line...!
I'm unable to understand this and work more and need help.
The formation of the tree works only in a 'sense' and I'm going the other way around? Don't know what it means but just something that comes to mind. :/
Thank you
K
P.S. - database is 10g R2.
Hello
Thanks for the display of the data of the sample; It is very useful.
What do you expect the result will be and why?
LEVEL = 1 contains all rows that meet the condition to START WITH. The rows that meet the condition
start_date = To_Date('01-apr-2014','dd-mon-yyyy')
in this case? Only the line you actually obtained.
LEVEL = N (where N > 1) contains all rows that meet the conditions regarding some FRONT CONNECT BY rank level = N - 1. Since the only line level = 1 to end_date = To_Date('10-apr-2014','dd-mon-yyyy'), lines satisfy the condition
End_date PRIOR = (start_date - 1).
? None. End_date PREREQUISITE is April 10, while rows with start_date April 11 would fulfill this condition, there is no line on LEVEL = 2 and the query stops there.
You would have expected this from your previous results. The line with the start_date April 1 had no children in the previous application, so there no children in any application that has the same State of CONNECT BY.
Maybe you meant the CONNECT BY condtion to be
End_date = BEFORE (start_date - 1).
-
Reg: Prior in hierarchical queries:
Hi Experts,
A little doubt - I've been working on the requests, but it still haunts me... Hierarchical queries
One thing I am more confused about is the prior clause.
I'll try to explain my concern below.
Here, the tree yesterday gets reversed by changing the clause PRIOR to 'Manager Id' to 'Employee Id' and vice versa.
Exactly how to understand where to put FORWARD... which column?
I can get my results just double check... but I just want to know the concept. So stupid right... but do not want to take this doubt more far. ;)
Please help guys.ranit@XE11GR2>> select * from 2 emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 17-DEC-08 800 20 7566 NORGAARD MANAGER 7839 01-APR-07 2975 20 7654 MARTIN SALESMAN 7698 28-SEP-07 1250 1400 30 7698 BLAKE MANAGER 7839 01-MAY-09 2850 30 7782 FOOTE MANAGER 7839 09-JUN-08 2450 10 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7839 ELLISON PRESIDENT 17-NOV-06 5000 10 7844 TURNER SALESMAN 7698 08-SEP-08 1500 0 30 7876 ADAMS CLERK 7788 18-JUN-07 1100 20 7900 JAMES CLERK 7698 03-DEC-07 950 30 7902 LOFSTROM ANALYST 7566 04-DEC-08 3000 20 7934 MILLER CLERK 7782 23-JAN-08 1300 10 12 rows selected. Elapsed: 00:00:00.04 ranit@XE11GR2>> select * from 2 emp 3 connect by empno = prior mgr 4 start with empno = 7698; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7698 BLAKE MANAGER 7839 01-MAY-09 2850 30 7839 ELLISON PRESIDENT 17-NOV-06 5000 10 Elapsed: 00:00:00.01 ranit@XE11GR2>> select * from 2 emp 3 connect by prior empno = mgr 4 start with empno = 7698; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7698 BLAKE MANAGER 7839 01-MAY-09 2850 30 7654 MARTIN SALESMAN 7698 28-SEP-07 1250 1400 30 7844 TURNER SALESMAN 7698 08-SEP-08 1500 0 30 7900 JAMES CLERK 7698 03-DEC-07 950 30 Elapsed: 00:00:00.07
Thank youOracle Database 11g Express Edition Release 11.2.0.2.0 - Production PL/SQL Release 11.2.0.2.0 - Production "CORE 11.2.0.2.0 Production" TNS for 32-bit Windows: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production
Vanessa B.I know the feeling!
START WITH gives you the first line of the result set.
CONNECT BY gets you the next row. At this point, you already have is the "before" line and the line that you get is the current line.
If the current line is supposed to be the Manager of the previous line, this means that Bishop PREREQUISITE = empno.
If the previous line is supposed to be the Manager of the current line, which means PRIOR empno = mgr.
Think AHEAD as referring to the line that you just received and "without any preconditions" as the line you want.
Another way of thinking that is to ask "what new information I receive?
If you say "Bishop PREREQUISITE = empno", you already know the Director of the previous row. New information will be the Director of the current line. As you continue, you will learn step by step who are managers.
If you say "PRIOR empno = mgr", you already know that the employee of the previous row. New information will be the new empno. So step by step, you will find the empnos.
You always ' move to before current. "Of mgr to empno" descends from the string, "empno to Bishop" goes to the top of the chain.
Published by: stew Ashton on February 16, 2013 11:57
-
Gites join vs hierarchical queries
Hello
Please tel me who must use a 1?
I have to get job list of the simple Manger, should I use self-join or hierarchical queries (CONNECT BY and earlier versions)?
Yours sincerelyHello
944768 wrote:
HelloPlease tel me who must use a 1?
I have to get job list of the simple Manger, should I use self-join or hierarchical queries (CONNECT BY and earlier versions)?It depends on your data and your needs.
Whenever you have a question, please post a small example of data (CREATE TABLE and INSERT statements) for all the tables involved, so people who want to help you can recreate the problem and test their ideas. Also post the results you want from this data, as well as an explanation of how you get these results from these data.
Explain, using specific examples, how you get these results from these data.
If you show what the problem using commonly available tables (suc as scott.emp, who has a hierarchy of level 4), then you do not have ot post sample data, just the results and explanations.
Always say what version of Oracle you are using (for example, 11.2.0.2.0).
See the FAQ forum {message identifier: = 9360002}If your hierarchy consists only of 2 levels, then a self-join will be probably more effective, simpler code and easier to maintain.
If you don't know how many levels in the hierarchy, then self-join is not an option. Use CONNECT BY or, if you have Oracle 11.2, a WITH recursive clause.
If you have a fixed number of levels (or an upper limit) greater than 2, then CONNECT BY (or a WITH recursive clause) will probably be the best.
-
How to order a tree balanced with SQL hierarchical queries
by searching the forum I found this
is there a way I can order this tree in alphabetical order so that the result looks like
LEVEL INDENTED_ENAME
---------- --------------------
1 KING BED
2 BLAKE
3 ALLEN
3 JAMES
MARTIN 3
3 TURNER
WARD 3
2 CLARK
3 MILLER
2 JONES
3 FORD
4 SMITH
3 SCOTT
4 ADAMS
-the original query-
SELECT THE LEVEL
, LPAD (' ', 3 * LEVEL) | Ename AS indented_ename
FROM scott.emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
;
LEVEL INDENTED_ENAME
---------- --------------------
1 KING BED
2 JONES
3 SCOTT
4 ADAMS
3 FORD
4 SMITH
2 BLAKE
3 ALLEN
WARD 3
MARTIN 3
3 TURNER
3 JAMES
2 CLARK
3 MILLERHello
Bodin wrote:
Hi Frank, I can order it selectively depending on the level, which means that only siblings stopped at third level, but rest of the brothers and sisters remain Nations United orderedIt's actually quite difficult. You can "ORDER of brothers and SŒURS BY CASE... ', like this:
SELECT LEVEL , LPAD (' ', 3 * LEVEL) || ename AS indented_ename FROM scott.emp START WITH mgr IS NULL CONNECT BY mgr = PRIOR empno ORDER SIBLINGS BY CASE WHEN job = 'MANAGER' THEN ename ELSE NULL END ;
In this case to get desired results in table scott.emp, as the lines are LEVEL = 2 if and only if use = "MANAGER".
But if you reference LEVEL in the CASE expression (for example, if you replace ' job = 'MANAGER' ' with "2 LEVEL =" above "), then you will get the error" ORA-00976: LEVEL, PRIOR or ROWNUM not allowed here. "
The best way I can think to do exactly what you asked is to do 2 CONNECT BY queries; one just to get the LEVEL and the other for the brothers and SŒURS ORDER BY:
{code}
WITH got_lvl AS
(
SELECT LEVEL AS lvl
Bishop
empno
ename
FROM scott.emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
)
SELECT lvl
, LPAD (' ', 3 * LEVEL) | Ename AS indented_ename
OF got_lvl
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
BROTHERS AND SŒURS OF ORDER OF CASES
ONCE lvl = 2 THEN ename
ANOTHER NULL
END
;
{code}
Why you can't simply "Brothers and SŒURS of ORDER BY ename" at all levels? If all you care is the order of the items of LEVEL = 2, then this is probably the most effective and simplest way. It really hurt anything if nodes on levels 3, 4, 5,... are in order, too?Here's something you can do if you want to order by different unique things to different levels:
{code}
WITH got_sort_key AS
(
SELECT LEVEL AS lvl
, LPAD (' ', 3 * LEVEL) | Ename AS indented_ename
empno
SYS_CONNECT_BY_PATH (LPAD (CASE
WHEN LEVEL = 2
THEN ename
Of OTHER TO_CHAR (empno)
END
10
)
, ','
) AS sort_key
FROM scott.emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
)
SELECT lvl
indented_ename
empno
OF got_sort_key
ORDER BY sort_key
;
{code}
However, all possible values of the CASE expression must uniquely identify the node; otherwise, the output won't necessarily hierarchical order. You can assign arbitrary unique IDS to the lines (using the ROW_NUMBER analytic function, for example), but that requires another subquery and is also complex and perhaps as ineffective as the solution above with 2 garages CONNECT. -
Hello
I wrote an application that allows the user to filter the data displayed based on several parameters, for example one of the parameters (b) is hierarchical, each element (with the exception of the root element) has a father and several sons, the hierarchy is managed by a specific table (LINKS), I need when the user selects b the result will include also all his descendants.
This is the query:
SELECT *.
R
JOIN IN-HOUSE RT ON R.A = RT. A
WHERE (R.B IN (select sub_id
the beginning of LINKS with father_id =: id
Connect prior sub_id = father_id)
or R.B =: id or: id = 0)
AND (R.A =: GOLD: a = 0)
ORDER OF R.B, R.A
The problem is that the query is so slow, it allows the application of stuck, when I've omitted the line: ' or R.B =: id or: id = 0 ' he not stuck but this line is necessary because the user may also fill the filter field or try to filter b himself and not his descendants.
Is it possible to improve the performance of this query or write it better?You can move the logic on r.b in the subquery.
There is a small chance that it could accelerate the entire query.
not testedSELECT * FROM R JOIN RT ON R.A = RT.A WHERE R.B IN (select sub_id from LINKS start with father_id = :id connect by prior sub_id= father_id UNION ALL select :id sub_id from dual UNION ALL select sub_id from LINKS where :id = 0 ) AND (R.A=:a or :a=0) ORDER BY R.B, R.A
Also see the ecexution use it and explain how to call the select statement.
A goal of optimization often used is wo writing several queries and call the right according to the parameters.
Different queries may be optimized independently of each other and hence faster query where everything is condensed into one big.pls/sql example
if :a=0 and :b=0 then SELECT * into... FROM R JOIN RT ON R.A = RT.A ORDER BY R.B, R.A; elsif :b=0 then SELECT * into... FROM R JOIN RT ON R.A = RT.A where R.A=:a ORDER BY R.B, R.A; elsif :a=0 then SELECT * into... FROM R JOIN RT ON R.A = RT.A WHERE R.B IN (select sub_id from LINKS start with father_id = :id connect by prior sub_id= father_id UNION ALL select :id sub_id from dual) ORDER BY R.B, R.A; else /* both parameters are selected */ SELECT * into... FROM R JOIN RT ON R.A = RT.A WHERE R.B IN (select sub_id from LINKS start with father_id = :id connect by prior sub_id= father_id UNION ALL select :id sub_id from dual) and R.A=:a ORDER BY R.B, R.A; end;
-
I have a table called 'File' with the data indicated below. I want the sql query to show the hierarchical output.
Enter values for the query: 2-11 tree shows two points (see "Input2" and "Input11"). The query now takes the values 2 and 11 and outputs hierarchical tree from root (see "Root") to the final sheets ('2, '12'), while the entries are as points of 'touch' inside the full tree-path, so I have the necessary output should be like 5 rows:
(0, null)-parent of the two inputs
(2, 0) - input2
(10,0) - parents of 'input11 '.
(11: 10) - input11
(12: 11) - leaf
I don't know how to write this query. Can help you.
Something like:
"Select...".
Connect prior ID = PARENT_ID.
--
Table "Folder" (ID, PARENT_ID).
Column PARENT_ID reference ID to create the hierarchy.
Example of data in the table:
(0, null)-root
(1, 0) - child '1 '.
(2, 0) - Input2
(3, 1)
(10,0) - child "10".
(11: 10) - chilc-child "11", Input11
(12: 11) - chilc-child "12".Hello
If you want to ignore a few lines in the file and only pay attention to the parameters, their ancestors and their descendants. Is this fair?
If so, do CONNECT it BY query on the results of a subquery which includes only the desired lines. In the example below, this query Tahina is be a UNION of two other CONNECT BY queries: one to get the ancestors of the parameters and the other for their descndents.VARIABLE input_a NUMBER VARIABLE input_b NUMBER EXEC :input_a := 2; EXEC :input_b := 11; WITH universe AS ( -- Descendents of parameters SELECT id, parent_id FROM folder START WITH parent_id IN (:input_a, :input_b) CONNECT BY parent_id = PRIOR id -- UNION -- Ancestors of parameters SELECT id, parent_id FROM folder START WITH id IN (:input_a, :input_b) CONNECT BY id = PRIOR parent_id ) SELECT SYS_CONNECT_BY_PATH (id, '/') AS path FROM universe START WITH parent_id IS NULL CONNECT BY parent_id = PRIOR id ;
Output of your sample data:
PATH ------------------------------ /0 /0/2 /0/10 /0/10/11 /0/10/11/12
-
Hierarchical queries for subnets
I need to write a hierarchical query for quite a number of (contiguous groups of IP addresses) IP subnets. What I'm hoping to do, is let the database do the bulk of the work here and I will not need to write code to do this. I'll do that if I have to but I would really rather not.
General information may be in order for those who do not know subnets. IP subnets have unique characteristics, based on network management standards (caveat: I'm not a guru/subnet on the network, but I know enough to be dangerous). The first thing to know is that a subnet is a contiguous block of IP addresses that help define the IP network protocol. Another thing is that an IP address can be converted to a binary or decimal/numeric value. This is useful because it can take us out of the sphere of analysis of strings and comparing a group of text values, which will eventually be converted to numbers in order to make meaningful comparisons anyway.
The result is that subnets can be defined by digital upper and lower limits. And the trick here is that some of these blocks of IP addresses live in the other blocks. Look at the data below and I'll explain if you need. In addition, the network address is the lower limit of the subnet and dissemination is the upper limit. This is a create table and examples of data from my dataset where you can see the IP addresses and name of each subnet and numeric limits for each subnet.
CREATE TABLE "SUBNET_DECIMAL_VALS" ( "SUBNET" VARCHAR2(4000 BYTE), "CIDR_BLOCK" VARCHAR2(30 BYTE), "NETWORK" VARCHAR2(4000 BYTE), "BROADCAST" VARCHAR2(4000 BYTE), "NETWORK_DEC" NUMBER, "BROADCAST_DEC" NUMBER ) ;
Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.0.0/20','/20','128.110.0.0','128.110.15.255',2154692608,2154696703); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.1.0/24','/24','128.110.1.0','128.110.1.255',2154692864,2154693119); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.4.0/22','/22','128.110.4.0','128.110.7.255',2154693632,2154694655); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.8.0/22','/22','128.110.8.0','128.110.11.255',2154694656,2154695679); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.12.0/22','/22','128.110.12.0','128.110.15.255',2154695680,2154696703); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.16.0/21','/21','128.110.16.0','128.110.23.255',2154696704,2154698751); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.16.0/22','/22','128.110.16.0','128.110.19.255',2154696704,2154697727); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.20.0/22','/22','128.110.20.0','128.110.23.255',2154697728,2154698751); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.24.0/22','/22','128.110.24.0','128.110.27.255',2154698752,2154699775); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.28.0/22','/22','128.110.28.0','128.110.31.255',2154699776,2154700799); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.28.0/24','/24','128.110.28.0','128.110.28.255',2154699776,2154700031); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.29.0/24','/24','128.110.29.0','128.110.29.255',2154700032,2154700287); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.30.0/24','/24','128.110.30.0','128.110.30.255',2154700288,2154700543); Insert into SUBNET_DECIMAL_VALS (SUBNET,CIDR_BLOCK,NETWORK,BROADCAST,NETWORK_DEC,BROADCAST_DEC) values ('128.110.31.0/24','/24','128.110.31.0','128.110.31.255',2154700544,2154700799);
SELECT * FROM SUBNET_DECIMAL_VALS subnet cidr network broadcast network_dec broadcast_dec 128.110.0.0/20 /20 128.110.0.0 128.110.15.255 2154692608 2154696703 128.110.1.0/24 /24 128.110.1.0 128.110.1.255 2154692864 2154693119 128.110.4.0/22 /22 128.110.4.0 128.110.7.255 2154693632 2154694655 128.110.8.0/22 /22 128.110.8.0 128.110.11.255 2154694656 2154695679 128.110.12.0/22 /22 128.110.12.0 128.110.15.255 2154695680 2154696703 128.110.16.0/21 /21 128.110.16.0 128.110.23.255 2154696704 2154698751 128.110.16.0/22 /22 128.110.16.0 128.110.19.255 2154696704 2154697727 128.110.20.0/22 /22 128.110.20.0 128.110.23.255 2154697728 2154698751 128.110.24.0/22 /22 128.110.24.0 128.110.27.255 2154698752 2154699775 128.110.28.0/22 /22 128.110.28.0 128.110.31.255 2154699776 2154700799 128.110.28.0/24 /24 128.110.28.0 128.110.28.255 2154699776 2154700031 128.110.29.0/24 /24 128.110.29.0 128.110.29.255 2154700032 2154700287 128.110.30.0/24 /24 128.110.30.0 128.110.30.255 2154700288 2154700543 128.110.31.0/24 /24 128.110.31.0 128.110.31.255 2154700544 2154700799
What I tried to do is a hierarchical query traditional and used more than and less than the comparisons in the where clause. I'm trying to find the limits of subnet (top and bottom numbers) that match among other numerical limits. This is an example, and it gives me the results I need.
select level, subnet, cidr_block cidr, network, broadcast, network_dec, broadcast_dec from poc_subnet_decimal_vals connect by nocycle prior network_dec > network_dec and broadcast_dec < broadcast_dec
Do I have to create from this, it is something like this:
Level Subnet CIDR Network Broadcast Network_Dec Broacast_Dec 1 128.110.0.0/20 /20 128.110.0.0 128.110.15.255 2154692608 2154696703 2 128.110.1.0/24 /24 128.110.1.0 128.110.1.255 2154692864 2154693119 2 128.110.4.0/22 /22 128.110.4.0 128.110.7.255 2154693632 2154694655 2 128.110.8.0/22 /22 128.110.8.0 128.110.11.255 2154694656 2154695679 2 128.110.12.0/22 /22 128.110.12.0 128.110.15.255 2154695680 2154696703 1 128.110.16.0/21 /21 128.110.16.0 128.110.23.255 2154696704 2154698751 2 128.110.16.0/22 /22 128.110.16.0 128.110.19.255 2154696704 2154697727 2 128.110.20.0/22 /22 128.110.20.0 128.110.23.255 2154697728 2154698751 2 128.110.24.0/22 /22 128.110.24.0 128.110.27.255 2154698752 2154699775 2 128.110.28.0/22 /22 128.110.28.0 128.110.31.255 2154699776 2154700799 3 128.110.28.0/24 /24 128.110.28.0 128.110.28.255 2154699776 2154700031 3 128.110.29.0/24 /24 128.110.29.0 128.110.29.255 2154700032 2154700287 3 128.110.30.0/24 /24 128.110.30.0 128.110.30.255 2154700288 2154700543 3 128.110.31.0/24 /24 128.110.31.0 128.110.31.255 2154700544 2154700799
Once, I get a hierarchical query of good work I can do the rest of the formatting with the values of the path and CYCLE but I'm not able to get a basic querying work. Does anyone have an idea of how to go on this subject using SQL only? I can write a PL/SQL procedure to add an ID of parent to each row, and then I know that I can create a hierarchical query from that but I was trying to avoid this method if possible.
Hello
Earl Lewis wrote:
I need to write a hierarchical query for quite a number of (contiguous groups of IP addresses) IP subnets. What I'm hoping to do, is let the database do the bulk of the work here and I will not need to write code to do this. I'll do that if I have to but I would really rather not.
General information may be in order for those who do not know subnets. IP subnets have unique characteristics, based on network management standards (caveat: I'm not a guru/subnet on the network, but I know enough to be dangerous). The first thing to know is that a subnet is a contiguous block of IP addresses that help define the IP network protocol. Another thing is that an IP address can be converted to a binary or decimal/numeric value. This is useful because it can take us out of the sphere of analysis of strings and comparing a group of text values, which will eventually be converted to numbers in order to make meaningful comparisons anyway.
The result is that subnets can be defined by digital upper and lower limits. And the trick here is that some of these blocks of IP addresses live in the other blocks. Look at the data below and I'll explain if you need. In addition, the network address is the lower limit of the subnet and dissemination is the upper limit. This is a create table and examples of data from my dataset where you can see the IP addresses and name of each subnet and numeric limits for each subnet.
- CREATE TABLE 'SUBNET_DECIMAL_VALS '.
- (
- VARCHAR2 (4000 BYTE) "SUBNET."
- VARCHAR2 (30 BYTE) "CIDR_BLOCK."
- VARCHAR2 (4000 BYTE) 'NETWORK ',.
- "BROADCASTING" VARCHAR2 (4000 BYTE),
- NUMBER OF "NETWORK_DEC."
- NUMBER OF 'BROADCAST_DEC '.
- ) ;
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.0.0/20','/20','128.110.0.0','128.110.15.255',2154692608,2154696703);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.1.0/24','/24','128.110.1.0','128.110.1.255',2154692864,2154693119);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.4.0/22','/22','128.110.4.0','128.110.7.255',2154693632,2154694655);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.8.0/22','/22','128.110.8.0','128.110.11.255',2154694656,2154695679);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.12.0/22','/22','128.110.12.0','128.110.15.255',2154695680,2154696703);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.16.0/21','/21','128.110.16.0','128.110.23.255',2154696704,2154698751);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.16.0/22','/22','128.110.16.0','128.110.19.255',2154696704,2154697727);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.20.0/22','/22','128.110.20.0','128.110.23.255',2154697728,2154698751);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.24.0/22','/22','128.110.24.0','128.110.27.255',2154698752,2154699775);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.28.0/22','/22','128.110.28.0','128.110.31.255',2154699776,2154700799);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.28.0/24','/24','128.110.28.0','128.110.28.255',2154699776,2154700031);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.29.0/24','/24','128.110.29.0','128.110.29.255',2154700032,2154700287);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.30.0/24','/24','128.110.30.0','128.110.30.255',2154700288,2154700543);
- Insert into SUBNET_DECIMAL_VALS (subnet, CIDR_BLOCK, NETWORK, BROADCAST, NETWORK_DEC, BROADCAST_DEC) values ('128.110.31.0/24','/24','128.110.31.0','128.110.31.255',2154700544,2154700799);
- SELECT * FROM SUBNET_DECIMAL_VALS
- subnet cidr network network_dec broadcast_dec broadcast
- 128.110.0.0/20 20 128.110.0.0 128.110.15.255 2154692608 2154696703
- 128.110.1.0/24 24 128.110.1.0 128.110.1.255 2154692864 2154693119
- 22 128.110.4.0/22 128.110.4.0 128.110.7.255 2154693632 2154694655
- 22 128.110.8.0/22 128.110.8.0 128.110.11.255 2154694656 2154695679
- 22 128.110.12.0/22 128.110.12.0 128.110.15.255 2154695680 2154696703
- 128.110.16.0/21 21 128.110.16.0 128.110.23.255 2154696704 2154698751
- 22 128.110.16.0/22 128.110.16.0 128.110.19.255 2154696704 2154697727
- 22 128.110.20.0/22 128.110.20.0 128.110.23.255 2154697728 2154698751
- 22 128.110.24.0/22 128.110.24.0 128.110.27.255 2154698752 2154699775
- 22 128.110.28.0/22 128.110.28.0 128.110.31.255 2154699776 2154700799
- 128.110.28.0/24 24 128.110.28.0 128.110.28.255 2154699776 2154700031
- 128.110.29.0/24 24 128.110.29.0 128.110.29.255 2154700032 2154700287
- 128.110.30.0/24 24 128.110.30.0 128.110.30.255 2154700288 2154700543
- 128.110.31.0/24 24 128.110.31.0 128.110.31.255 2154700544 2154700799
. I'm trying to find the limits of subnet (top and bottom numbers) that match among other numerical limits. This is an example, and it gives me the results I need.What I tried to do is a hierarchical query traditional and used more than and less than the comparisons in the where clause
- Select the level, subnet, cidr_block cidr, broadcast network, network_dec, broadcast_dec
- of poc_subnet_decimal_vals
- nocycle to connect before network_dec > network_dec and broadcast_dec<>
Do I have to create from this, it is something like this:
- Level of subnet CIDR network broadcast Network_Dec Broacast_Dec
- 1 20 128.110.0.0/20 128.110.0.0 128.110.15.255 2154692608 2154696703
- 2 128.110.1.0/24 24 128.110.1.0 128.110.1.255 2154692864 2154693119
- 2 128.110.4.0/22 22 128.110.4.0 128.110.7.255 2154693632 2154694655
- 2 128.110.8.0/22 22 128.110.8.0 128.110.11.255 2154694656 2154695679
- 2 128.110.12.0/22 22 128.110.12.0 128.110.15.255 2154695680 2154696703
- 1 128.110.16.0/21 21 128.110.16.0 128.110.23.255 2154696704 2154698751
- 2 128.110.16.0/22 22 128.110.16.0 128.110.19.255 2154696704 2154697727
- 2 128.110.20.0/22 22 128.110.20.0 128.110.23.255 2154697728 2154698751
- 2 128.110.24.0/22 22 128.110.24.0 128.110.27.255 2154698752 2154699775
- 2 128.110.28.0/22 22 128.110.28.0 128.110.31.255 2154699776 2154700799
- 3 128.110.28.0/24 24 128.110.28.0 128.110.28.255 2154699776 2154700031
- 3 128.110.29.0/24 24 128.110.29.0 128.110.29.255 2154700032 2154700287
- 3 128.110.30.0/24 24 128.110.30.0 128.110.30.255 2154700288 2154700543
- 3 128.110.31.0/24 24 128.110.31.0 128.110.31.255 2154700544 2154700799
Once, I get a hierarchical query of good work I can do the rest of the formatting with the values of the path and CYCLE but I'm not able to get a basic querying work. Does anyone have an idea of how to go on this subject using SQL only? I can write a PL/SQL procedure to add an ID of parent to each row, and then I know that I can create a hierarchical query from that but I was trying to avoid this method if possible.
This is the right forum. I can see why there is only a single forum for SQL and PL/SQL, but I do not see why they suggest that there are separate forums.
I'm not sure that you understand the problem. In the ouptu (the line whose number 11) you have
- 2 128.110.28.0/22 22 128.110.28.0 128.110.31.255 2154699776 2154700799
I guess this level = 2 means that the row is a child of a few rows, but which? It was numbered line 7:
- 1 128.110.16.0/21 21 128.110.16.0 128.110.23.255 2154696704 2154698751
? This would mean that the child has a higher than its parent network_dec.
I think you want something like this:
WITH got_parent AS
(
SELECT s. *- or whatever the desired columns
, (
SELECT MIN (ss.subnet) DUNGEON (DENSE_RANK FIRST ORDER BY ss.broadcast_dec - ss.network_dec)
OF subnet_decimal_vals ss
WHERE ss.network_dec<=>=>
AND ss.broadcast_dec > = s.broadcast_dec
AND ss.subnet <> s.subnet
) As a parent
OF s subnet_decimal_vals
)
SELECT LEVEL AS lvl
subnet, cidr_block, network, broadcast, network_dec, broadcast_dec
OF got_parent
START WITH parent IS NULL
Parent = subnet PRIOR CONNECTION
;
The result is:
LVL SUBNET NETWORK BROADCAST NETWORK_DEC BROADCAST_DEC CID
--- ---------------- --- ---------------- ---------------- ----------- -------------
1 20 128.110.0.0/20 128.110.0.0 128.110.15.255 2154692608 2154696703
2 128.110.1.0/24 24 128.110.1.0 128.110.1.255 2154692864 2154693119
2 128.110.4.0/22 22 128.110.4.0 128.110.7.255 2154693632 2154694655
2 128.110.8.0/22 22 128.110.8.0 128.110.11.255 2154694656 2154695679
2 128.110.12.0/22 22 128.110.12.0 128.110.15.255 2154695680 2154696703
1 128.110.16.0/21 21 128.110.16.0 128.110.23.255 2154696704 2154698751
2 128.110.16.0/22 22 128.110.16.0 128.110.19.255 2154696704 2154697727
2 128.110.20.0/22 22 128.110.20.0 128.110.23.255 2154697728 2154698751
1 22 128.110.24.0/22 128.110.24.0 128.110.27.255 2154698752 2154699775
1 22 128.110.28.0/22 128.110.28.0 128.110.31.255 2154699776 2154700799
2 128.110.28.0/24 24 128.110.28.0 128.110.28.255 2154699776 2154700031
2 128.110.29.0/24 24 128.110.29.0 128.110.29.255 2154700032 2154700287
2 128.110.30.0/24 24 128.110.30.0 128.110.30.255 2154700288 2154700543
2 128.110.31.0/24 24 128.110.31.0 128.110.31.255 2154700544 2154700799
Close enough to what you have requested, but not exact. If this isn't what you want, explain how you can tell if a line is one ancestor of the other in the tree.
I guess that this subnet is unique. If this is not the case, the above query will have to be changed a little, but only a little.
-
Legacy and hierarchical queries
Hi all
Using the RDBMS 11.2.0.3, I would like to know if there was a way to "inherit" a parent row values when you use a hierarchical query.
For example, with these values:
CREATE TABLE foohh ( id NUMBER, parent NUMBER, name VARCHAR2(64), continent VARCHAR2(32) ); INSERT INTO foohh VALUES ( 1, null, 'United States', 'AMERICA' ) ; INSERT INTO foohh VALUES ( 2, 1, 'California', null ) ; INSERT INTO foohh VALUES ( 3, 2, 'San Francisco', null ) ; INSERT INTO foohh VALUES ( 4, 3, 'Golden Gate', null ) ; INSERT INTO foohh VALUES ( 5, null, 'China', 'ASIA' ) ; INSERT INTO foohh VALUES ( 6, 5, 'Beijing', null ) ; INSERT INTO foohh VALUES ( 7, 6, 'Great Wall', null ) ;
I would like to be able to view the continent of all lines.
The following query returns the leaves, but I don't see their continent:
SELECT id ,connect_by_root(parent) parent ,sys_connect_by_path(name, '-->') path ,nvl( continent, 'unknown' ) continent FROM foohh WHERE connect_by_root(parent) is null and connect_by_isleaf=1 CONNECT BY PRIOR id=parent ;
CONTINENT OF PARENT ID PATH
---------- ---------- ------------------------------------------------------------ ------------------------------
4-> United States-> California-> San Francisco-> Golden Gate unknown
7-> China-> Beijing-> great unknown wallIs there a clever way to do this?
Thank you
Anthony
Include below in him SELECT query.
Continent CONNECT_BY_ROOT
-
Hierarchical queries with Rollup sum (CONNECTED BY GROUP BY ROLLUP)
Hi all
Imagine the following scenario: I have an ACCOUNT table that contains the accounts and their hierarchy (currently 5 levels) and a BALANCE table that holds the record for the balance of the accounts. Only CHILD accounts (level 5) have records in the table for BALANCE. Simple example:
What I need in this scenario is to run a hierarchical query, where each node, I calculate the sum of all its children (in TERMINAL nodes that are child accounts, this amount is the value of the balances itself). End result would be: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);
I tried many ways and found a solution that works for a fixed amount of levels, basically he built the hierarchy and calculates the SYS_CONNECT_BY_PATH, then divides it as a regular expression and using GROUP BY ROLLUP to calculate the highest levels. Then I assemble again, now with the calculated values. Here's the example query:TOT -> 10000 ANA1 -> 3000 4801001 -> 2000 4801001 -> 1000 ANA2 -> 7000 4802001 -> 3000 4802002 -> 4000
All is 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, regardless of the number of levels, amounts of parent are all wound like that?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_acct
Thank you very much in advance! Best regards!
Thiago
Published by: Thiago Sep 6, 2011 11:31
Published by: Thiago Sep 6, 2011 13:01select account_code, ( select sum(balance_amount) from accounts a2, balances b where b.account_code(+) = a2.account_code start with a2.account_code = a1.account_code connect by a2.parent_account = prior a2.account_code ) balance_amount from accounts a1 / ACCOUNT_CODE BALANCE_AMOUNT --------------- -------------- TOT 10000 ANA1 3000 4801001 3000 4801002 ANA2 7000 4802001 7000 4802002 7 rows selected. SQL>
SY.
-
Building the tree balanced with SQL hierarchical queries
Hi all
I have the following hierarchical data with different levels of subtree:
A0
-A001
-A00101
A1
-A101
A2
-A201
-A20101
-A201010001
A0 subtree has 3 levels, A1 subtree has 2 levels and subtree of the A3 is level 4. I want to generate a tree balanced on the data with all levels of the subtree equal to the maximum number of levels available in the whole tree which, in this particular case, is 4.
I don't know that it is possible with SQL. Script to generate the above mentioned are as below:
CREATE TABLE codes_tree
(node_id VARCHAR2 (10))
parent_node_id VARCHAR2 (10)
);
INSERT INTO codes_tree VALUES ('A0', NULL);
INSERT INTO codes_tree VALUES ('A001', 'A0');
INSERT INTO codes_tree VALUES ('A00101', 'A001');
---
INSERT INTO codes_tree VALUES ('A1', NULL);
INSERT INTO codes_tree VALUES ('A101', 'A1');
---
INSERT INTO codes_tree VALUES ('A2', NULL);
INSERT INTO codes_tree VALUES ('A201', 'A2');
INSERT INTO codes_tree VALUES ('A20101', 'A201');
INSERT INTO codes_tree VALUES ('A201010001', 'A20101');
Any help will be much appreciated.
Thank you... Best regards
Published by: naive2Oracle on May 12, 2011 19:40
Published by: naive2Oracle on May 12, 2011 19:41Hello
Of course, you can do it in SQL.
One way is to take the normal output of hierarchical and manipulate the result set so that the leaves are repeated as often as necessary to make all branches of the same length. I have Oracle 10.2 available right now, so here's a solution that will work in Oracle 10 (and more):WITH original_hierarchy AS ( SELECT node_id , LEVEL AS lvl , CONNECT_BY_ISLEAF AS isleaf , ROWNUM AS rnum FROM codes_tree START WITH parent_node_id IS NULL CONNECT BY parent_node_id = PRIOR node_id ) , got_max_lvl AS ( SELECT o.* , MAX (lvl) OVER () AS max_lvl FROM original_hierarchy o ) SELECT LPAD ( ' ' , 3 * ( ( d.lvl + NVL (c.rnum, 1) - 1 ) - 1 ) ) || CASE WHEN c.rnum > 1 THEN '*' || d.node_id || '*' ELSE d.node_id END AS display_id FROM got_max_lvl d LEFT OUTER JOIN got_max_lvl c ON d.isleaf = 1 AND c.rnum <= 1 + d.max_lvl - d.lvl ORDER BY d.rnum , c.rnum ;
With the help of Oracle 11.2, it would be preferable to generate original_hierarchy as above, but to manipulate using a WITH recursive clause.
Analytical functions often interfere with CONNECT BY, so I used a separate subquery to get max_lvl, do CONNECT BY in a sub-querry and analytic function in a separate subquery. I don't know what is needed on all versions.Output of your sample data:
DISPLAY_ID ------------------------------- A0 A001 A00101 *A00101* A1 A101 *A101* *A101* A2 A201 A20101 A201010001
Below is a generic version of the same query, which I used to test this on scott.emp:
DEFINE table_name = scott.emp DEFINE id_col = empno DEFINE parent_id_col = mgr DEFINE display_col = ename WITH original_hierarchy AS ( SELECT &display_col AS display_txt , LEVEL AS lvl , CONNECT_BY_ISLEAF AS isleaf , ROWNUM AS rnum FROM &table_name START WITH &parent_id_col IS NULL CONNECT BY &parent_id_col = PRIOR &id_col ) , got_max_lvl AS ( SELECT o.* , MAX (lvl) OVER () AS max_lvl FROM original_hierarchy o ) SELECT LPAD ( ' ' , 3 * ( ( d.lvl + NVL (c.rnum, 1) - 1 ) - 1 ) ) || CASE WHEN c.rnum > 1 THEN '*' || d.display_txt || '*' ELSE d.display_txt END AS display_id FROM got_max_lvl d LEFT OUTER JOIN got_max_lvl c ON d.isleaf = 1 AND c.rnum <= 1 + d.max_lvl - d.lvl ORDER BY d.rnum , c.rnum ;
Output:
DISPLAY_ID ----------------------------- KING JONES SCOTT ADAMS FORD SMITH BLAKE ALLEN *ALLEN* WARD *WARD* MARTIN *MARTIN* TURNER *TURNER* JAMES *JAMES* CLARK MILLER *MILLER*
Published by: Frank Kulash, May 13, 2011 06:38
Adding the generic version -
hierarchical queries - error: ORA-30929: clause ORDERBY brothers and SŒURS unauthorized
Hello
I have a hierarchical query in which, I automatically generate unordered list. I needed to get the children in the same level, so I used the brothers and sisters of the order by clause, but the procedure did not compile and threw an error Ora-30929 - brothers and sisters Order By Clause not allowed here.
This is the query.
SELECT CASE WHEN LAG(LEVEL,1,0) (ORDER OF ROWNUM) > = LEVEL THEN "< li >".
(Level) lead CASE of OTHER COURSES (ORDER OF ROWNUM) WHEN LEVEL THEN
CASE WHEN ROWNUM = 1 THEN ' < ul id = "sidebarmenu1" 'ELSE' < ul' END | ' > < li > '
On the OTHER CASE WHEN ROWNUM = 1 THEN ' < ul id = "sidebarmenu1" 'ELSE' < ul ' END: ' > < li > ' END END |
"< span >' | daevmt.short_menu_item |' </span >' |
LEVEL of CASE - LEAD(LEVEL,1,1) (ROWNUM ORDINANCE) WHEN - 1 THEN NULL WHEN 0 THEN "< /li >".
ELSE REPLACE (LPAD ('* ', LEVEL-LEAD(LEVEL,1,1) (ORDER OF ROWNUM),'* '), ' * ',' < /li > < /ul > < /li > ')
END | CASE WHEN AHEAD (LEVEL, 1, 0) (ORDER OF ROWNUM) = 0 THEN '< /ul >"END of another null unordered_list, daevmt.menu_item, daevmt.link_url, daevmt.menu_id,.
daevmt.above_menu_id
OF dae_vs_my_tasks daevmt
START WITH daevmt.above_menu_id = "TOPMENU".
CONNECT BY PRIOR = daevmt.above_menu_id Daevmt.menu_id
Brothers and SŒURS of ORDER BY daevmt.display_order;
Can someone please help what is wrong in my query?
Thanks in advance,
Natarajan
Published by: Nikita on March 7, 2011 23:26
Published by: Nikita on March 7, 2011 23:28
Published by: Nikita on March 7, 2011 23:28According to the Oracle documentation, this error is caused by 'ORDER brothers' and SŒURS clause of having in a query that is not a "CONNECT BY" clause that is clearly not the case here. I suspect it's because you use analytical functions 'LEAD' and 'LAG '. I took your statement, replaced the names of table and column with some in a table, I also has a structure of hierarchical and got the same error. After removing all the functions of 'LEAD' and 'LAG' it run OK.
I don't think that helps you all.
You may create another table with the contents of this table by adding 4 columns for rownum, level (level) lead and lag (level). Then use this table to generate your unsorted list html code. -
Hierarchical queries - difficult
Hi all
Thanks in advance,
Please answer as soon as possible
I would like to know some suggestions for repatriated PRDCT_CUSTM_HIER_SK not duplicated using hierarchical values to oracle 10 g
suggest on how to modify the query without changing the status of CONNECT BY PRIOR
Only if the query should never return values in a double PRDCT_CUSTM_HIER_SK.
If you view the example we have 4 duplicate values
Consider the table as below
PRDCT_CUSTM_HIER_SK - ITEM_ID - PRNT_ID
27945 - 74-0
28977 - 75-74
28100 - 85-75
28538 - 86-85
29557 - 115-74
29477 - 116-115
28117 - 360-86
30894 - 360-85
29039 - 390-115
30876 - 431-360
30839 - 432-360
30883 - 433-360
30863 - 434-360
I EXECUTED THE GIVEN SCRIPT
SELECT
LEVEL CUSTM_HIER_LVL_ID
CUSTM_HIER_ITEM_ID ITEM_ID,
PRNT_ID CUSTM_HIER_PRNT_ID
lpad (PRDCT_CUSTM_HIER_SK, level + length (PRDCT_CUSTM_HIER_SK) * 10-10,'-') PRDCT_CUSTM_HIER_SK
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 2,'/ ')) CUSTM_HIER_SK_LVL1
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 3,'/ ')) CUSTM_HIER_SK_LVL2
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 4,'/ ')) CUSTM_HIER_SK_LVL3
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 5,'/ ')) CUSTM_HIER_SK_LVL4
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 6,'/ ')) CUSTM_HIER_SK_LVL5
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 7,'/ ')) CUSTM_HIER_SK_LVL6
, TO_NUMBER (GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_SK,'/'), 8,'/ ')) CUSTM_HIER_SK_LVL7
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 2,'/ ') CUSTM_HIER_NM_LVL1
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 3,'/ ') CUSTM_HIER_NM_LVL2
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 4,'/ ') CUSTM_HIER_NM_LVL3
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 5,'/ ') CUSTM_HIER_NM_LVL4
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 6,'/ ') CUSTM_HIER_NM_LVL5
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 7,'/ ') CUSTM_HIER_NM_LVL6
, GET_TOKEN (SYS_CONNECT_BY_PATH(PRDCT_CUSTM_HIER_LVL_1_NM,'/'), 8,'/ ') CUSTM_HIER_NM_LVL7
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 2,'/ ') CUSTM_HIER_ITEM_ID_LVL1
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 3,'/ ') CUSTM_HIER_ITEM_ID_LVL2
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 4,'/ ') CUSTM_HIER_ITEM_ID_LVL3
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 5,'/ ') CUSTM_HIER_ITEM_ID_LVL4
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 6,'/ ') CUSTM_HIER_ITEM_ID_LVL5
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 7,'/ ') CUSTM_HIER_ITEM_ID_LVL6
, GET_TOKEN (SYS_CONNECT_BY_PATH(ITEM_ID,'/'), 8,'/ ') CUSTM_HIER_ITEM_ID_LVL7
CONNECT_BY_ROOT PRDCT_CUSTM_HIER_SK PRDCT_CUSTM_ROOT_SK
PRDCT_CUSTM_PRNT_SK PRDCT_CUSTM_HIER_SK PRIOR
PRDCT_CUSTM_HIER_LVL_1_NM PRDCT_CUSTM_HIER_NM
PRDCT_CUSTM_HIER_LVL_1_NM BEFORE CUSTM_HIER_PRNT_NM
CONNECT_BY_ROOT PRDCT_CUSTM_HIER_LVL_1_NM CUSTM_HIER_ROOT_NM
, SYS_CONNECT_BY_PATH (PRDCT_CUSTM_HIER_LVL_1_NM, ' / ') CUSTM_HIER_NM_PATH
PRDCT_CUSTM_HIER_SS_CD PRDCT_CUSTM_HIER_SS_CD
PRDCT_BRND_NM PRDCT_BRND_NM
PRDCT_BRND_ID PRDCT_BRND_ID
PRDCT_BRND_SK PRDCT_BRND_SK
Of
OBJECTIVE TMP_PRDCT_CUSTM_HIER
START BY ITEM_ID = (SELECT MIN (ITEM_ID) OF BI. TMP_PRDCT_CUSTM_HIER)
CONNECT PRIOR ITEM_ID = PRNT_ID
/
THE OUTPUT IS AS FOLLOWS
1-74 - 0 - 27945
2-115-74-29557
3-390-115-29039
3-116-115-29477
2-75-74-28977
3-85-75-28100
4-360-85-30894
*5 -- 431 -- 360 -- ----------------------------------------30876*
*5 -- 432 -- 360 -- ----------------------------------------30839*
*5 -- 433 -- 360 -- ----------------------------------------30883*
*5 -- 434 -- 360 -- ----------------------------------------30863*
4 -- 86 -- 85 -- ------------------------------28538
5 -- 360 -- 86 -- ----------------------------------------28117
*6 -- 431 -- 360 -- --------------------------------------------------30876*
*6 -- 432 -- 360 -- --------------------------------------------------30839*
*6 -- 433 -- 360 -- --------------------------------------------------30883*
*6 -- 434 -- 360 -- --------------------------------------------------30863*
-
Hierarchical queries for table of account
HelloW to all
I have a Table that's graphic account
The column of this table is
Acc_id and Acc_name
I insert data into this table of account
Insert into the COA
values
* (01, 'ASSETS'); *
values
* (01001, 'active'); *
values
* (01002, "fixed assets"); *
values
* (010010001, 'banks'); *
values
* (010010002, "cash"); *
values
* (01001000100001, 'Metrol politan Bank'); *
values
* (01001000100002, 'Royal Bank'); *
values
* (01001000100003, 'stander charted Bank'); *
values
* (01001000200001, 'body'); *
values
* ('01001000200002, Patty Cash"); *
This is my case, now I need to create a hierarchical tree
That looks like this
* 01 - active *.
-010001 active+.
Bank-010010001+.
Metrol politan Bank---01001000100001+.
Royal - 01001000100002 Bank+.
---01001000100003 stander charted Bank+.
---010010002 cash+.
-01001000200001 money in hand+.
01001000200002 Patty Cash+.
Capital - 010002+.
---010020001 active machines.
---01002000100001 needle Machine+.
Machine GGT - 01002000100002+.
-010020002 computer active+.
-01002000200001 Server computer+.
-01002000200002 other computer+.
Hope you guys understand that I need the hierarchical query to do this kind of tree
Concerning
ThereseLike this?
SQL> select 2 lpad('-',(level-1)*4,'-')|| acc_id || 3 ' ' || acc_name as tree 4 from coa 5 connect by prior 6 acc_id = rtrim(substr(acc_id,1,instr(acc_id,'0',-1)),'0') 7 start with rtrim(substr(acc_id,1,instr(acc_id,'0',-1)),'0') is null 8 ; TREE ------------------------------------------------------------ 01 ASSETS ----01001 Current Assets --------010010001 Banks ------------01001000100001 Metrol Politan Bank ------------01001000100002 Royal Bank ------------01001000100003 Stander Charted Bank --------010010002 Cash ------------01001000200001 Cash in Hand ------------01001000200002 Patty Cash ----01002 Fixed Assets 10 rows selected.
Best regards
Maxim
-
hierarchical queries find single parent
Hello
How can I find the only father, and all your 'child', example
with tt as (select 205070 id1 , null father from dual union all select 205071 , 205070 from dual union all select 2, null from dual union all select 3,2 from dual union all select 4,3 from dual union all select 10, null from dual union all select 5,4 from dual )
I want to get the ID1 = 2 and all of your children, 3,4,5
How can he do?
Using
Oracle Database 11 g Enterprise Edition Release 11.2.0.3.0 - 64 bit Production
Hello
muttleychess wrote:
Hello
How can I find the only father, and all your 'child', example
- with tt as (select 205070 id1, father of all null double union)
- Select 205071, 205070 of all the double union
- Select 2, union null value double all the
- Select 3.2 in union double all the
- Select 4.3 in union double all the
- choose 10, union null double all the
- Select double 5.4
- )
I want to get the ID1 = 2 and all of your children, 3,4,5
How can he do?
Using
Oracle Database 11 g Enterprise Edition Release 11.2.0.3.0 - 64 bit Production
Thanks for the display of the data of the sample; that really helps.
Why do you want 2 and his descendants, but not 205070 and his descendants?
Maybe you are looking for
-
Contacts not syncing between iCloud/iOS and "on my Mac".
Greetings, I very recently discovered contacts that I create on iOS website or iCloud does not synchronize to the section "on my Mac" (i.e. a local copy) of the Contacts and contacts created in the group "on my Mac" inside the Contacts.app will not s
-
Why my screen have a checkered pattern, but when I start in safe MODE it disappears?
Why my screen have a checkered pattern, but when I start in safe MODE it disappears?
-
the computer restarted unexpectedly or encountered an unexpected error
How to fix computer restarted unexpectedly or encountered an unexpected error.
-
Computer crashes randomly...
Computer began to 'hang up' or randomly freeze for periods of a few seconds to a few minutes when you use Windows Mail, Internet Explorer, Firefox, etc.I tried to do a "restore" to factory settings on the advice of the manufacturer of the computer, b
-
I need my local calendar in my z10 be transferred to my new q10 of any way to do this simply? Geez. I have os 10.2 in my z10 and new q10. I'm trying to synchronize the local calendar w / my mac version of 6.0 2012 calendar and outlook 2003 ole... I'm