Oracle Version 11G.
I have a requirement to show the data in a Hierarchy manner. It will shown as a TREE structure in the UI.
I have 3 tables
I) T_MAIN,T_ITEMS_MAIN It's having the Static data.
II) T_PURCH_ITEMS Having purchased items for each end user.(items selected From T_ITEMS_MAIN).
1) T_MAIN Table
ID PARENT_ID PRD_NME
--- -------- -------
1 STORE
2 1 BASE
3 1 WORKERS
4 1 PURCHASE
5 4 STATIONARY
6 5 S_PENS
7 5 S_PAPERS
8 4 COLOR_ITM
9 8 COL_ERASERS
10 8 COL_SCALES
2) T_ITEMS_MAIN Table
ITEM_NO ID ITEM_NME
------ -- --------
1 2 BASE1
2 2 BASE2
3 3 WORKER1
4 3 WORKER2
5 6 S_PEN1
6 6 S_PEN2
7 7 S_PAPER1
8 7 S_PAPER2
9 9 COL_ERASERS1
10 9 COL_ERASERS2
11 10 COL_SCALES1
12 10 COL_SCALES2
3) T_PURCH_ITEMS data which are having customer data
PUR_NME ITEM_NO
------ ------
STEVE 1
STEVE 2
STEVE 4
STEVE 6
STEVE 7
STEVE 10
STEVE 12
<b>I NEED THE OUTPUT IN BELOW MANNER TO MAIN THE TREE STRUCTURE, LET ME KNOW IF ANY OTHER EASY WAY TO MAINTAIN THE TREE STRUCTURE ALSO.
ID PARENT_ID ITEM/PRDT_Nme
--- --------- -------------
1 STORE
2 1 BASE
1 2 BASE1
2 2 BASE2
3 1 WORKERS
4 3 WORKER2
4 1 PURCHASE
5 4 STATIONARY
6 5 S_PENS
6 6 S_PEN2
7 5 S_PAPERS
7 7 S_PAPER1
8 4 COLOR_ITM
9 8 COL_ERASERS
10 9 COL_ERASERS2
10 8 COL_SCALES
12 10 COL_SCALES2
Find the all the table and data DML and DDL stms.
CREATE TABLE T_MAIN (ID NUMBER,PARENT_ID NUMBER,PRD_NME VARCHAR2(20),CONSTRAINT T_MAIN_PK PRIMARY KEY(ID));
CREATE TABLE T_ITEMS_MAIN (ITEM_NO NUMBER,ID NUMBER,ITEM_NME VARCHAR2(20), CONSTRAINT fk_T_ITMES_MAIN FOREIGN KEY (ID) REFERENCES T_MAIN(ID) );
CREATE TABLE T_PURCH_ITEMS ( PUR_NME VARCHAR2(10),ITEM_NO NUMBER);
INSERT INTO T_MAIN VALUES (1,'','STORE');
INSERT INTO T_MAIN VALUES (2,1,'BASE');
INSERT INTO T_MAIN VALUES (3,1,'WORKERS');
INSERT INTO T_MAIN VALUES (4,1,'PURCHASE');
INSERT INTO T_MAIN VALUES (5,4,'STATIONARY');
INSERT INTO T_MAIN VALUES (6,5,'S_PENS');
INSERT INTO T_MAIN VALUES (7,5,'S_PAPERS');
INSERT INTO T_MAIN VALUES (8,4,'COLOR_ITM');
INSERT INTO T_MAIN VALUES (9,8,'COL_ERASERS');
INSERT INTO T_MAIN VALUES (10,8,'COL_SCALES');
COMMIT;
INSERT INTO T_ITEMS_MAIN VALUES(1,2,'BASE1');
INSERT INTO T_ITEMS_MAIN VALUES(2,2,'BASE2');
INSERT INTO T_ITEMS_MAIN VALUES(3,3,'WORKER1');
INSERT INTO T_ITEMS_MAIN VALUES(4,3,'WORKER2');
INSERT INTO T_ITEMS_MAIN VALUES(5,6,'S_PEN1');
INSERT INTO T_ITEMS_MAIN VALUES(6,6,'S_PEN2');
INSERT INTO T_ITEMS_MAIN VALUES(7,7,'S_PAPER1');
INSERT INTO T_ITEMS_MAIN VALUES(8,7,'S_PAPER2');
INSERT INTO T_ITEMS_MAIN VALUES(9,9,'COL_ERASERS1');
INSERT INTO T_ITEMS_MAIN VALUES(10,9,'COL_ERASERS2');
INSERT INTO T_ITEMS_MAIN VALUES(11,10,'COL_SCALES1');
INSERT INTO T_ITEMS_MAIN VALUES(12,10,'COL_SCALES2');
COMMIT;
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',1);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',2);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',4);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',6);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',7);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',10);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE'11);
INSERT INTO T_PURCH_ITEMS VALUES('STEVE',12);
COMMIT;
Thanks for providing a complete set of create tables + inserts!
The key to getting started with this is to union (all) t_main and t_items_main.
The items should appear under the corresponding main row. t_items_main.id gives this value. So map this to parent_id.
To prevent you joining main rows back to items as children:
- Set item_no to null when selecting from t_main
- Set id to null when selecting from t_items_main
Giving:
select t.id, t.parent_id, t.prd_nme, null item_no
from t_main t
union all
select null id, t.id parent_id, t.item_nme prd_nme, t.item_no
from t_items_main t;
ID PARENT_ID PRD_NME ITEM_NO
1 STORE
2 1 BASE
3 1 WORKERS
4 1 PURCHASE
5 4 STATIONARY
6 5 S_PENS
7 5 S_PAPERS
8 4 COLOR_ITM
9 8 COL_ERASERS
10 8 COL_SCALES
2 BASE1 1
2 BASE2 2
3 WORKER1 3
3 WORKER2 4
6 S_PEN1 5
6 S_PEN2 6
7 S_PAPER1 7
7 S_PAPER2 8
9 COL_ERASERS1 9
9 COL_ERASERS2 10
10 COL_SCALES1 11
10 COL_SCALES2 12
If you only want to display items a user has purchased, stick a where exists in against t_items_main.
You can then build your tree on the results of this using standard hierarchical queries.
If you're on 11.2 or higher, you can use a recursive with:
with rws as (
select t.id, t.parent_id, t.prd_nme, null item_no from t_main t
union all
select null id, t.id parent_id, t.item_nme prd_nme, t.item_no
from t_items_main t
where exists (
select * from t_purch_items p
where p.item_no = t.item_no
)
), tree (id, parent_id, name, item_no, lev) as (
select id, parent_id, prd_nme, null, 0 lev
from rws
where parent_id is null
union all
select r.id, r.parent_id, r.prd_nme, r.item_no, t.lev + 1 lev
from tree t
join rws r
on t.id = r.parent_id
)
search depth first by id set order1
select nvl(id, item_no) id, parent_id, lpad(' ', lev * 2) || name
from tree;
ID PARENT_ID LPAD('',LEV*2)||NAME
1 STORE
2 1 BASE
1 2 BASE1
2 2 BASE2
3 1 WORKERS
4 3 WORKER2
4 1 PURCHASE
5 4 STATIONARY
6 5 S_PENS
6 6 S_PEN2
7 5 S_PAPERS
7 7 S_PAPER1
8 4 COLOR_ITM
9 8 COL_ERASERS
10 9 COL_ERASERS2
10 8 COL_SCALES
12 10 COL_SCALES2
If you're not, you can stick with a traditional connect by:
with rws as (
select t.id, t.parent_id, t.prd_nme, null item_no from t_main t
union all
select null id, t.id parent_id, t.item_nme prd_nme, t.item_no
from t_items_main t
where exists (
select * from t_purch_items p
where p.item_no = t.item_no
)
)
select nvl(id, item_no) id, parent_id,
lpad(' ', (level-1)*2) || prd_nme item_prod_name
from rws
start with parent_id is null
connect by nocycle prior id = parent_id;
ID PARENT_ID ITEM_PROD_NAME
1 STORE
2 1 BASE
1 2 BASE1
2 2 BASE2
3 1 WORKERS
4 3 WORKER2
4 1 PURCHASE
5 4 STATIONARY
6 5 S_PENS
6 6 S_PEN2
7 5 S_PAPERS
7 7 S_PAPER1
8 4 COLOR_ITM
9 8 COL_ERASERS
10 9 COL_ERASERS2
10 8 COL_SCALES
12 10 COL_SCALES2
Results using test scripts in question as provided.