简体   繁体   中英

View to return the root node given any children (in Oracle)

We manufacture equipment, and we give every unit we produce a serial number (s/n). We have a parent/child table which we use to establish the relationship between the top-level assemblies and its children. I am providing a sample layout of such table below.

CREATE TABLE PAR_CHI
(PARENT_SN VARCHAR2(50 BYTE) NOT NULL,
 CHILD_SN VARCHAR2(50 BYTE) NOT NULL,
 PRIMARY KEY (PARENT_SN, CHILD_SN));

I have some data that can be loaded in this table, found below.

insert into PAR_CHI values (' ', '135887957');
insert into PAR_CHI values ('135887957', '135562597');
insert into PAR_CHI values ('135562597', '135424162');
insert into PAR_CHI values ('135424162', '135422839');
insert into PAR_CHI values ('135887957', '135623876');
insert into PAR_CHI values ('135623876', '135519894');
insert into PAR_CHI values ('135519894', '135517981');
insert into PAR_CHI values ('135887957', '136526805');

I have no experience with hierarchical queries, so I have done some online research about it and how it works. So far I have learned that a query like the one below can be used to find the 'tree' (or hierarchy) for a specific top-level assembly to return its full genealogy.

select PARENT_SN, CHILD_SN, level, connect_by_root(CHILD_SN) as root, sys_connect_by_path(CHILD_SN, '/') as path, connect_by_isleaf
from PAR_CHI
start with CHILD_SN = '135887957'
connect by PARENT_SN = prior CHILD_SN;

I have also learned that a query like the one below could be used to traverse the hierarchy in opposite direction (given a component s/n, to find its parent and all the way to the top-level assembly).

select PARENT_SN, CHILD_SN, level, connect_by_root(CHILD_SN) as root, sys_connect_by_path(CHILD_SN, '/') as path, connect_by_isleaf
from PAR_CHI
start with CHILD_SN = '135517981'
connect by CHILD_SN = prior PARENT_SN;

There is a way to get the 'real' parent for a specific serial number if 'connect_by_isleaf' is used, as shown below.

select PARENT_SN, CHILD_SN, level, connect_by_root(CHILD_SN) as root, sys_connect_by_path(CHILD_SN, '/') as path, connect_by_isleaf
from PAR_CHI
where connect_by_isleaf = 1
start with CHILD_SN = '135517981'
connect by CHILD_SN = prior PARENT_SN;

I have a specific need to create a view or a table (preferably a view), but this object, whatever it is, cannot call another object to build a dataset (let me explain: for instance, in SSRS Reports we can call a store procedure that would build a dataset given specific search criteria, and then the report would display the records in the dataset). This object must be ready for the user to perform a straight 'select statement' on it, and get the desired results.

The object should return one row every time, showing the top-level assembly s/n (root) given any s/n the user is searching for.

Let me provide some examples of expected results given search data.

  1. If the user enters s/n '135887957', the dataset would return one row showing the values below:

Root S/N Searched S/N 135887957

This record corresponds to the top-level assembly itself, and the 'Root s/n' column is blank (not null).

  1. If the user enters s/n '135562597', the dataset would return one row showing the values below.

Root S/N Searched S/N 135887957 135562597

This record shows that the entered s/n '135562597' has root s/n '135887957'. Since this is a level 2 component, the result returns the top-level assembly.

  1. If the user enters s/n '135519894', the dataset would return one row showing the values below.

Root S/N Searched S/N 135887957 135519894

This record shows that the entered s/n '135519894' has root s/n '135887957' (strictly speaking, the 'parent' of this level 3 component is '135623876', but we need to get the top-level assembly, not the 'real' parent).

  1. If the user enters s/n '135422839', the dataset should return one row showing the values below.

Root S/N Searched S/N 135887957 135422839

This record shows that the entered s/n '135422839' has root s/n '135887957' (strictly speaking, the 'parent' of this level 4 component is '135424162', but we need to get the top-level assembly, not the 'real' parent).

As you can see, we do not really need any other data like the level, or the 'real' parent' or the path, but if we can add it, it would be helpful; just the s/n that corresponds to the top-level assembly. One big difference between the code that I have seen in other posts and my specific need is that we do not have a 'starting point'; all the queries out there use a 'start with' statement, but since we need to put this in a view, we do not really have that starting record to start searching from.

Could anyone advice how we can build this object given the needs we have?

Thanks in advance.

In the example, the root element should not have any parent, if you remove the blank and recreate the table as this then your existing solution should work.

CREATE TABLE PAR_CHI
(PARENT_SN VARCHAR2(50 BYTE) ,
 CHILD_SN VARCHAR2(50 BYTE) NOT NULL
);
create or replace view test_hierarchy as 
select PARENT_SN, CHILD_SN as ROOT, level level_in, 
connect_by_root(CHILD_SN) as Searched_val, 
sys_connect_by_path(CHILD_SN, '/') as path
from PAR_CHI
where connect_by_isleaf = 1
--start with CHILD_SN = '135422839'
connect by CHILD_SN = prior PARENT_SN
;

you can query this view and pass the serial number to search and it will give you all the required fields

样本

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM