Format:
SELECT column
FROM table_name
Start with column = value
Connect by prior parent primary key = Child foreign key
Select lpad ('', 4 * (level-1) | name, job, id, super from emp
Start with super is null
Connect by prior id = super
Example:
Raw data: select no, q from a_example2
NO NAME
----------------------------------------
001 a01
001 a02
001 a03
001 a04
001 a05
002 b01
003 c01
003 c02
004 d01
005 e01
005 e02
005 e03
005 e04
005 e05
The result is as follows:
001 a01; a02; a03
002 b01
003 c01; c02
004 d01
005 e01; e02; e03; e04; e05
Ideas:
1. There is a connect by clause after ORACLE8.1 to retrieve the entire tree data.
Create table a_example1
(
No char (3) not null,
Name varchar2 (10) not null,
Parent char (3)
)
Insert into a_example1
Values ('001', 'old Wang ', null)
Insert into a_example1
Values ('20170901', 'lil', null)
Insert into a_example1
Values ('002', 'Kingdom 1', '001 ')
Insert into a_example1
Values ('20180101', 'Lee 1', '20180101 ')
Insert into a_example1
Values ('003 ', 'king 2', '001 ')
Insert into a_example1
Values ('20180101', 'dali 2', '20180101 ')
Insert into a_example1
Values ('003 ', 'John 1', '002 ')
Insert into a_example1
Values ('20170301', 'Lee 1', '20160301 ')
NO NAME PARENT
001 Lao Wang
101 Lao Li
002 King 1 001
102 Dali 1 101
003 King 2 001
103 Dali 2 101
003 John 1 002
103 Xiao Li 1 102
// Retrieve data by family tree
Select * from a_example1
Select level, sys_connect_by_path (name, '/') path
From a_example1
Start with/* name = 'old Wang 'and */parent is null
Connect by parent = prior no
Result:
1/Lao Wang
2/Lao Wang/dawang 1
3/Lao Wang/dawang 1/Xiao wang 1
2/Lao Wang/dawang 2
1/Lao Li
2/Lao Li/Dali 1
3/Lao Li/Dali 1/Xiao Li 1
2/Lao Li/Dali 2
Based on the above ideas, we only need to make the original data into the following structure:
NO NAME
001 a01
001 a01/a02
001 a01/a02/a03
001 a01/a02/a03/a04
001 a01/a02/a03/a04/a05
002 b01
003 c01
003 c01/c02
004 d01
005 e01
005 e01/e02
005 e01/e02/e03
005 e01/e02/e03/e04
005 e01/e02/e03/e04/e05
Group by NO. The maximum value is the result.
NO NAME
001 a01/a02/a03/a04/a05
002 b01
003 c01/c02
004 d01
005 e01/e02/e03/e04/e05
SQL statement:
Select no, max (sys_connect_by_path (name, ';') result from
(Select no, name, rn, lead (rn) over (partition by no order by rn) rn1
From (select no, name, row_number () over (order by no, name desc) rn from a_example2)
)
Start with rn1 is null connect by rn1 = prior rn
Group by no
Statement Analysis:
1. select no, name, row_number () over (order by no, name desc) rn from a_example2
Sort by NO in ascending order, and sort by NAME in descending order to generate pseudo columns to form a Tree Structure
NO NAME RN
001 a03 1
001 a02 2
001 a01 3
002 b01 4
003 c02 5
003 c01 6
004 d01 7
005 e05 8
005 e04 9
005 e03 10
005 e02 11
005 e01 12
2. select no, name, rn, lead (rn) over (partition by no order by rn) rn1
From (select no, name, row_number () over (order by no, name desc) rn from a_example2)
Generate a family spectrum, that is, the child node corresponds to the parent node, and the corresponding relationship is through rn AND rn1. Lead is the RN value of the previous record.
No name rn RN1 001 a03 1 2 --
Note: For NO = 001, the next record RN = 2 001 a02 2 3 -- Note: For NO = 001, next record RN = 3 001 a01 3 -- Note: For NO = 001, the next record RN IS NULL
002 b01 4 003 c02 5 6 003 c01 6 004 d01 7 005 e05 8 9 005 e04 9 10 005 e03 10 11 005 e02 11 12 005 e01 12
3. select no, sys_connect_by_path (name, ';') result from
(Select no, name, rn, lead (rn) over (partition by no order by rn) rn1
From (select no, name, row_number () over (order by no, name desc) rn from a_example2 ))
Start with rn1 is null connect by rn1 = prior rn
Generate tree
NO RESULT
001; a01
001; a01; a02
001; a01; a02; a03
002; b01
005; e01
005; e01; e02
005; e01; e02; e03
005; e01; e02; e03; e04
005; e01; e02; e03; e04; e05
003; c01
003; c01; c02
004; d01
Group the above results by NO, and obtain the maximum value of the result. Therefore, change the preceding statement
Select no, max (sys_connect_by_path (name, ';') result from
(Select no, name, rn, lead (rn) over (partition by no order by rn) rn1
From (select no, name, row_number () over (order by no, name desc) rn from a_example2)
)
Start with rn1 is null connect by rn1 = prior rn
Group by no
Obtain the expected result.