Hierarchical Queries help me
hi,
What is the usage of 'Connect' , 'Prior' in hierarchical queries and
what does it mean??
http://download-uk.oracle.com/docs/cd/B19306_01/server.102/b14200/queries003.htm
Cheers
Sarma.
Similar Messages
-
Help needed in understanding the concept of hierarchical queries
I really need help in this matter. I have a flafile containing about 4000 rows. It is from my supplier, it's structure is as follows:
create table Flatfile
(Pgroup varchar2(30),
Pclass varchar2(30),
Manufacturer varchar2(30),
Article varchar2(30),
Price Number(6,2));
Insert into Flatfile Values
('Application Software','Database Software','Oracle','Oracle 10G',115);
Insert into Flatfile Values
('Application Software','Database Software','Microsoft','MS SQL Server 2000',200);
Insert into Flatfile Values
('Application Software','Spreadsheet Software','Microsoft','Excel',100);
Insert into Flatfile Values
('Monitor','15"','Acer','Acer 15"" TFT superscreen',199);
Insert into Flatfile Values
('Monitor','15"','Sony','Sony R1500 flat',225);
Insert into Flatfile Values
('Monitor','17"','Philips','Philips Flatscreen',250);
Insert into Flatfile Values
('Monitor','19"','Viewsonic','Viewsonic PLasma Monitor',275);
Insert into Flatfile Values
('Processor','AMD','AMD','FX-55',600);
Insert into Flatfile Values
('Processor','Intel','Intel','P4 3 GHZ',399);
My goal is to make a hierarchical query with the start with and connect by clauses. From what I have read is that I need to normalize the data of the flatfile.
How do I achieve a table which I can query so that the query will represent the hierarchy that exists. Namely
Pgroup
++Pclasse
Application Software
++Database Software
++Spreadsheet Software
So a 2-level hierarchy. I'd like to understand this simple concept first. I built on the knowledge that I gain. So the questions are:
1.What do I need to do to make the table so that I can use a hierarchical query on it?
2. How should the query syntax be?
3. Is it also possible to get the data in the hierarchical query sorted asec?
I would only like to use the simple structures of the start with and connect by clauses first. I've read there are some new additions to 10G. The problem with the examples used by the tutorials is that the tables are already made so that they are suitable for hierarchical queries. I hope to understand it by this example. And take it a step further.
Sincerely,
PetePrimarily hierarchy query serves to process tree-like structures which RDBMS simulates using through parent-child relation, often in a single table (see famoust
EMP table where employee can have the manager who is an employee at the same time).
In your case it could look like:
SQL> select pgroup, pclass from flatfile;
PGROUP PCLASS
Application Software Database Software
Application Software Database Software
Application Software Spreadsheet Software
Monitor 15"
Monitor 15"
Monitor 17"
Monitor 19"
Processor AMD
Processor Intel
Application Software
Monitor
Processor
12 rows selected.
SQL> select decode(level,1,pclass,' ' || pclass), Manufacturer from flatfile
2 start with pgroup is null
3 connect by prior pclass = pgroup
4 /
DECODE(LEVEL,1,PCLASS,''||PCLASS MANUFACTURER
Application Software
Database Software Oracle
Database Software Microsoft
Spreadsheet Software Microsoft
Monitor
15" Acer
15" Sony
17" Philips
19" Viewsonic
Processor
AMD AMD
Intel Intel
12 rows selected.The hierarchy syntax is described completely in the documentation including
LEVEL and PRIOR keywords.
As for the ordering question you can use siblings ordering:
SQL> select decode(level,1,pclass,' ' || pclass), Manufacturer from flatfile
2 start with pgroup is null
3 connect by prior pclass = pgroup
4 order siblings by 1 desc
5 /
DECODE(LEVEL,1,PCLASS,''||PCLASS MANUFACTURER
Processor
Intel Intel
AMD AMD
Monitor
19" Viewsonic
17" Philips
15" Acer
15" Sony
Application Software
Spreadsheet Software Microsoft
Database Software Oracle
Database Software Microsoft
12 rows selected.Rgds. -
Alternative for Hierarchical Queries
Hi all,
Is there any other way to implement the Hierachical Query in Oracle. Let us assume the following example of the Scott.emp Table. The output of the table must be in a Hierarchical manner as follows :
ORG_CHART EMPNO MGR JOB
KING 7839 PRESIDENT
JONES 7566 7839 MANAGER
SCOTT 7788 7566 ANALYST
ADAMS 7876 7788 CLERK
FORD 7902 7566 ANALYST
SMITH 7369 7902 CLERK
BLAKE 7698 7839 MANAGER
ALLEN 7499 7698 SALESMAN
WARD 7521 7698 SALESMAN
MARTIN 7654 7698 SALESMAN
TURNER 7844 7698 SALESMAN
JAMES 7900 7698 CLERK
CLARK 7782 7839 MANAGER
MILLER 7934 7782 CLERK
The above structure can be achieved using the following implementation by using the clauses namely CONNECT BY PRIOR, LEVEL and START WITH :
SELECT LPAD(' ',2*(LEVEL-1)) || ename org_chart,
empno, mgr, job
FROM emp
START WITH job = 'PRESIDENT'
CONNECT BY PRIOR empno = mgr;
The above query works fine without any issues.
But is there any other way to implement the above logic without using the above hierarchical query clauses.
Please help me on the above.
Thanks in advance.
Regards
RajThanks.
Why I require this implementation is we have an software which runs both on Oracle and SQL Server, we accomplish the same very easily in Oracle by using the Hierarchical Queries already available in Oracle. But there is no such predefined keywords to implement in SQL server. That is the purpose of the above.
When we can achieve the same in a alternative way in Oracle, the same I feel can be implemented in SQL server.
Raj
Not without dropping into PLSQL, but this is not easy, and why bother, if your query works OK? -
I've a table with these values.
ID Name Parent_ID
0 Organization1 null
1 Organization2 0
2 Organization3 0
3 Organization4 0
4 Organization5 1
5 Organization6 1
6 Organization7 2
7 Organization8 2
8 Organization9 4
9 Organization10 4
10 Organization11 6
11 Organization12 8.
Need to write a sql query in Oracle 9i to get the Hierarchy of Organization12:
The output should be:
Organization1
Organization9
Organization5
Organization2
Organization1.
The query should be dynamic. If I give Organization11, I should get the hierarchy of Organization11.
Organization1
Organization7
Organization3
Organization1.
Could anyone please help me in getting this output.See the followings links for hierarchical queries:
http://philip.greenspun.com/sql/trees.html
http://www.psoug.org/reference/connectby.html
--Manohar -
Hierarchical Queries / Rowsets via JDBC?
I have an application that requires data from an SQL database to be displayed in a hierarchical directed graph (i.e. a JTree). Is it possible to construct Hierarchical Queries that return Hierarchical Rowsets in servlets via JDBC? This would be akin to using a Microsoft ADODB Hierarchical Recordset object, but I need a Java solution that's portable and isn't dependent on proprietary extensions in a server (i.e. iPlanet, etc.).
Any help would be appreciated.
Thanks.Is it possible to construct Hierarchical Queries that
return Hierarchical Rowsetsin servlets via JDBC?No. JDBC only speaks in flat rows and columns.
What type of hierarchical rowset are you referring to? Is it multidimensional data? For example MSSqlServer OLAP with row, column and measure dimensions? Or, is it simply grouped data for which you are both summarizing and displaying detail? -
Self join vs Hierarchical Queries
Hi,
please tel me which one 1 should use ?
i have to get simple manger's employ list, should i use self join or hierarchical queries(CONNECT BY and prior)?
yours sincerelyHi,
944768 wrote:
Hi,
please tel me which one 1 should use ?
i have to get simple manger's employ list, should i use self join or hierarchical queries(CONNECT BY and prior)?It depends on your data and your requirements.
Whenever you have a question, please post a little sample data (CREATE TABLE and INSERT statements) for all the tables involved, so the people who want to help you can re-create the problem and test their ideas. Also post the results you want from that data, and an explanation of how you get those results from that data.
Explain, using specific examples, how you get those results from that data.
If you can show what the problem is using commonly available tables (suc as scott.emp, which has a 4-level hierarchy) then you don't have ot post any sample data, just the results and the explanation.
Always say what version of Oracle you're using (e.g. 11.2.0.2.0).
See the forum FAQ {message:id=9360002}
If your hierarchy consists only of 2 levels, then a self-join will probably be more efficient, simpler to code, and easier to maintain.
If you don't know how many levels are in the hierarchy, then self-join isn't an option. Use CONNECT BY or, if you have Oracle 11.2, a recursive WITH clause.
If you have a fixed number of levels (or an upper bound) greater than 2, then CONNECT BY (or a recursive WITH clause) will probably be best. -
Hierarchical Queries - Challenging
Hi all,
Thanks in advance,
please reply as soon as possible
Let me know some suggestions to get the non duplicate PRDCT_CUSTM_HIER_SK values using Hierarchical Querie of oracle 10g
suggest on how to edit the query without changing the CONNECT BY PRIOR condition
On only one condition the query should never return duplicate PRDCT_CUSTM_HIER_SK values.
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 HAVE EXECUTED THE GIVEN SCRIPT
SELECT
LEVEL CUSTM_HIER_LVL_ID
,ITEM_ID CUSTM_HIER_ITEM_ID
,PRNT_ID CUSTM_HIER_PRNT_ID
,lpad(PRDCT_CUSTM_HIER_SK,length(PRDCT_CUSTM_HIER_SK) + level *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
,PRIOR PRDCT_CUSTM_HIER_SK PRDCT_CUSTM_PRNT_SK
,PRDCT_CUSTM_HIER_LVL_1_NM PRDCT_CUSTM_HIER_NM
,PRIOR PRDCT_CUSTM_HIER_LVL_1_NM 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
FROM
BI.TMP_PRDCT_CUSTM_HIER
START WITH ITEM_ID = (SELECT MIN(ITEM_ID) FROM BI.TMP_PRDCT_CUSTM_HIER)
CONNECT BY 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*Hi,
Since item_id 360 has two parents (item_ids 85 and 86),, then 360 and all of its descendants will appear twice in the output.
If you want them to appear only once, you have to tell the query to only count one of the two parents of 360.
Here's one way to ignore all but one parent of any item:
WITH got_r_num AS
SELECT product_custm_hier_sk
, item_id
, print_id
, ROW_NUMBER () OVER ( PARTITION BY item_id
ORDER BY prnt_id
) AS r_num
FROM bi.tmp_prdct_custm_hier
-- WHERE ... -- any filtering goes here
, one_parent AS
SELECT *
FROM got_r_num
WHERE r_num = 1
SELECT ... -- Continue with your query
FROM one_parent -- only change to main query
START WITH ...That is, instead of using the actual table in the FROM clause, you use the result set of a Top-N query.
If you don't always want the lowest parent to be the one used, then just change the analytic ORDER BY clause.
If you need help, post a little sample data (CREATE TABLE and INSERT statements) and the results you want from that data.
When posting output (or any formatted text) on this site, type these 6 characters:
\(small letters only, inside curly brackets) before and after each section of formatted text, to preserve the spacing. -
Map the hierarchical queries pseudo column level
Is it possible to map the hierarchical queries pseudo column level in the Workbench?
I have an object for which I use connect by queries. I would like to map the pseudo column level. is this possible? if yes, how
If the mapping is not possible how do I get the level using a report query?
Is there any other way to retrive level?
Thanks
Edited by: amehta5 on May 4, 2010 11:52 AM
Edited by: amehta5 on May 4, 2010 11:55 AMThanks James, appreciate your feedback.
I tried report.addItem("level", builder.getFunction("LEVEL"));
but the query TopLink generates has LEVEL() and it errors out.
Code -
Expression startExpr = null;
Expression connectBy = builder.get("manager");
Vector<Expression> order = new Vector<Expression>();
order.addElement(builder.get("name"));
report.setHierarchicalQueryClause(startExpr, connectBy, order);
report.addAttribute("name");
report.addItem("level", builder.getFunction("LEVEL"));
Query generated by TOpLink - SELECT NAME, ID, LEVEL() FROM EMPLOYEE WHERE (EMPLOYEE_TYPE = ?) CONNECT BY PRIOR EMPLOYEE.MANAGER_ID = EMPLOYEE.ID ORDER SIBLINGS BY NAME
bind => [M]
Edited by: amehta5 on May 6, 2010 6:11 AM -
Hierarchical queries (mother, father,...)
Hi guys,
a have a problem that I think it can be solved whit hierarchical queries.
the question is like this. I have a person ...and each person has a mother and a father. (the mother/father may be or not be in my table)
so my table configuration will be like:
create table person
(id number,
name varchar2 (100),
mother_id number,
father_id number
the questions I need to answer are like:
1. return all persons that have all grandparents (or grand grand parents) in this table.(including parents). so entire genealogic tree is intact
e.g. if the grandfather is not in the table I will not display that person we cannot display that person
I have something like:
insert into person values (1,'alin', 4, 5); ----id 1 has parents in my table: 4 the mother, 5 the father
insert into person values (4,'mother_1', 8,null); ----id 4 has only her mother in table
insert into person values (5, 'father_1',9,10);--id 5(who is father of 1) with 9 as mother and 10 as father
insert into person values (8, 'grant',null ,null );
insert into person values (9, 'aaa',11,12);
insert into person values (10,'bbb',13,14);
insert into person values (11,'ccc',null ,null);
insert into person values (12, 'ddd',null ,null);
insert into person values (13,'eee',15,16);
insert into person values (14,'fff',17,18);
insert into person values (15,'ggg',null ,null);
insert into person values (16,'hhh',null ,null);
insert into person values (17,'iii',null ,null);
insert into person values (18,'jjjj',null,null);
in this configuration my select should return id 5 with his relatives and id 10 with this relatives because only them have all relatives in table:
id | name | mother | father | mather_mother (mm) | father_mother (fm) | mf | ff
5 | 'father' | 9 | 10 | 11 | 12 | 13 | 14
10 | bbb | 13 | 14 | 15 | 16 | 17 | 18
and second select ..if I input an id..lets say 1 to get the same result..like:
id | name | mother | father | mather_mother (mm) | father_mother (fm) | mf | ff
1 | 'alin' | 4 | 5 | 8 | null | 9 | 10and maybe at some point I want to show level 3(with grand grand parents)
please se the attached picture:
link: [http://picasaweb.google.com/alinbor/Tree#5428860555382426514]
ThanksHi,
Here's a revised version of the String Aggregation approach.
For :level_cnt = 3, it produces this output:
ROOT_ID ROOT_NAME ANCESTORS
M F MM FM MF FF
5 father_1 9 10 11 13 12 14
10 bbb 13 14 15 17 16 18The last part, starting with UNION, gets the "header " row.
The first part, before UNION, is exactly what I posted yesterday.
WITH got_tree AS
SELECT id
, name
, CONNECT_BY_ROOT id AS root_id
, CONNECT_BY_ROOT name AS root_name
, LEVEL AS level_num
, CASE
WHEN id = PRIOR mother_id
THEN 'M'
ELSE 'F'
END AS mf_flag
, SYS_CONNECT_BY_PATH ( CASE
WHEN id = PRIOR mother_id
THEN 'M'
ELSE 'F'
END
) AS gender_path
FROM person p
CONNECT BY ( id = PRIOR mother_id
OR id = PRIOR father_id
AND LEVEL <= :level_cnt
, got_sa_num AS
SELECT t.*
, ROW_NUMBER () OVER ( PARTITION BY root_id
ORDER BY level_num
, mf_flag DESC
, gender_path DESC
) AS sa_num
FROM got_tree t
SELECT root_id
, root_name
, REPLACE ( SYS_CONNECT_BY_PATH ( TO_CHAR (id, '9999')
) AS ancestors
FROM got_sa_num
WHERE sa_num = POWER (2, :level_cnt) - 1
START WITH sa_num = 2
CONNECT BY sa_num = PRIOR sa_num + 1
AND root_id = PRIOR root_id
UNION
SELECT NULL AS root_id
, NULL AS root_name
, REPLACE ( SYS_CONNECT_BY_PATH ( LPAD ( SUBSTR ( REPLACE ( gender_path
, 2
, 5 -- 1 + number of '9's in TO_CHAR, 13 lines up
) AS ancestors
FROM got_sa_num
WHERE sa_num = POWER (2, :level_cnt) - 1
START WITH sa_num = 2
CONNECT BY sa_num = PRIOR sa_num + 1
AND root_id = PRIOR root_id
ORDER BY root_id NULLS FIRST
; -
Hierarchical queries no longer working with 11gr2
Hi, next hierarchical query:
SELECT REF(f) FROM STORE1.FOLDER_TABLE f
WHERE LEVEL > 1 START WITH REF(f) = ? CONNECT BY PRIOR f.key$ = f.header$.parentKey
used to work fine with 11gr1, while with 11gr2 it raises ORA-00904: "F": invalid identifier.
This seems to occur for all hierarchical queries.Here's a simple script for SQL developer:
CREATE OR REPLACE TYPE Test_type AS OBJECT (
key RAW(16),
parentKey RAW(16))
CREATE TABLE Test_table OF Test_type (
key DEFAULT SYS_GUID() PRIMARY KEY)
OBJECT IDENTIFIER IS PRIMARY KEY;
SELECT REF(f) FROM Test_table f
START WITH f.parentKey IS NULL
CONNECT BY PRIOR f.key = f.parentKey
Returning ref(f) raises ORA-00904: "F": invalid identifier.
Returning f.key succeeds. -
Hierarchal queries and USER_DEPENDENCIES
I'm new to Hierarchal queries; I have a Hierarchal query on USER_DEPENDENCIES that does not work and gives an error
'TSPKG_ES' is a package the works; I'm trying to do query to see what is calls
SELECT LEVEL, D.*
FROM DBA_DEPENDENCIES D
START WITH D.name = 'TSPKG_ES'
CONNECT BY PRIOR D.name = D.referenced_name
Result = ORA-00600: internal error code, arguments: [sorsikbeg_1], [5], [0] ,[],[],[],[],[]
SELECT LEVEL, D.*
FROM DBA_DEPENDENCIES D
START WITH D.name = 'DATATESTSPKG_ES'
CONNECT BY PRIOR D.referenced_name = D.name
Result = ORA=0143: CONNECT BY loop in user dataOS = Microsoft Windows XP V2002 Service Pack 3
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
"CORE 10.2.0.4.0 Production"
TNS for 64-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production -
Hierarchical queries and nested tables
Hallo,
Assume you have the following data structure:
SQL> desc mgr
Name Null? Typ
MGRNO NUMBER
LASTNAME VARCHAR2(20)
EMPS EMPTYPE_TAB
SQL> desc emptype_tab
emptype_tab TABLE OF EMP_TYPE
Name Null? Typ
EMPNO NUMBER
LASTNAME VARCHAR2(20)
I would like to select rows in a hierarchical order to get an output like this:
LAST_NAME EMPNO MGRNO LEVEL
King 100 1
Cambrault 148 100 2
Bates 172 148 3
..but i have absolutely no clue how to use the hierarchical query clause with a nested table.
can anybody help me?scott@ORA92> CREATE OR REPLACE TYPE emp_type AS OBJECT
2 (empno NUMBER,
3 lastname VARCHAR2(20))
4 /
Type created.
scott@ORA92> CREATE OR REPLACE TYPE emptype_tab AS TABLE OF emp_type
2 /
Type created.
scott@ORA92> CREATE TABLE mgr
2 (MGRNO NUMBER,
3 LASTNAME VARCHAR2(20),
4 EMPS EMPTYPE_TAB)
5 NESTED TABLE emps STORE AS emps_nt
6 /
Table created.
scott@ORA92> INSERT INTO mgr VALUES (NULL, NULL, emptype_tab (emp_type (100, 'King')))
2 /
1 row created.
scott@ORA92> INSERT INTO mgr VALUES (100, 'King', emptype_tab (emp_type (148, 'Cambrault')))
2 /
1 row created.
scott@ORA92> INSERT INTO mgr VALUES (148, 'Cambrault', emptype_tab (emp_type (172, 'Bates')))
2 /
1 row created.
scott@ORA92> SELECT * FROM mgr
2 /
MGRNO LASTNAME
EMPS(EMPNO, LASTNAME)
EMPTYPE_TAB(EMP_TYPE(100, 'King'))
100 King
EMPTYPE_TAB(EMP_TYPE(148, 'Cambrault'))
148 Cambrault
EMPTYPE_TAB(EMP_TYPE(172, 'Bates'))
scott@ORA92> SELECT m.mgrno, m.lastname as mgr, e.empno, e.lastname as emp
2 FROM mgr m, TABLE (emps) e
3 /
MGRNO MGR EMPNO EMP
100 King
100 King 148 Cambrault
148 Cambrault 172 Bates
scott@ORA92> SELECT lastname, empno, mgrno, LEVEL
2 FROM (SELECT m.mgrno, e.lastname, e.empno
3 FROM mgr m, TABLE (emps) e)
4 START WITH mgrno IS NULL
5 CONNECT BY PRIOR empno = mgrno
6 /
LASTNAME EMPNO MGRNO LEVEL
King 100 1
Cambrault 148 100 2
Bates 172 148 3
scott@ORA92> -
Version: Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
Hello,
I'm hoping I can get help with a Hierarchical Query.
My base table contains Projects with a Group ID. Each Group can have the same Project Name so displaying the information in a Select List on an form for data entry can be very confusing. I'm hoping I can get a query that would produce the output below.
Please let me know if I haven't provided the necessary information.
The tables involved are:
CREATE TABLE projects
PROJECT_ID NUMBER,
PROJECT_NAME VARCHAR2(100),
GROUP_ID NUMBER
CREATE TABLE vertical_group
GROUP_ID NUMBER,
GROUP_NAME VARCHAR2(50)
The data is:
INSERT INTO projects(project_id,project_name,group_id)
VALUES (1,'Proj Grp 1',1);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (2,'Proj Grp 1',1);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (3,'Proj Grp 1',1);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (4,'Proj Grp 1',1);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (5,'Proj Grp 1',1);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (6,'Proj Grp 2',2);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (7,'Proj Grp 2',2);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (8,'Proj Grp 2',2);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (9,'Proj Grp 2',2);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (10,'Proj Grp 3',3);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (11,'Proj Grp 3',3);
INSERT INTO projects(project_id,project_name,group_id)
VALUES (12,'Proj Grp 3',3);
INSERT INTO vertical_group(group_id,group_name)
VALUES (1,'Group 1');
INSERT INTO vertical_group(group_id,group_name)
VALUES (2,'Group 2');
INSERT INTO vertical_group(group_id,group_name)
VALUES (3,'Group 3');
The desired output is:
Group 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Group 2
Proj Grp 2
Proj Grp 2
Proj Grp 2
Proj Grp 2
Group 3
Proj Grp 3
Proj Grp 3
Proj Grp 3
Thanks,
JoeNo hierarchical query is needed. Use UNION ALL and weights:
with t as (
select 'Group ' || group_id name,
group_id,
1 weight
from projects
group by group_id
union all
select ' ' || project_name,
group_id,
2 weight
from projects
select name
from t
order by group_id,
weight,
name
NAME
Group 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Proj Grp 1
Group 2
Proj Grp 2
Proj Grp 2
Proj Grp 2
Proj Grp 2
NAME
Group 3
Proj Grp 3
Proj Grp 3
Proj Grp 3
15 rows selected.
SQL>
SY. -
Based on your inputs-I studied and created the below objects.I apologise for asking lengthy questions,but i
need your help very much now to proceed next.
There is a COMPANY WHICH has many divisions/departments in it.
These divisions has employees.
*{color:#0000ff}--Created employee table which employee_id and Salary.*
**employees (*empid,salary){color}*
*{color:#0000ff}***DO i need to put the DEPT_ID and Manager_id in the EMPLOYEES table? {color}*
*{color:#0000ff}--Presently,iCreated a relationship table to have EMPLOYEE"S MANAGER information.a manager is an employee itself.{color}*
*{color:#0000ff}--Created a table for EMPLOyee and department---RELATIONSHIP ---> empl_id and dept_id{color}*
The COMPANY has numerous Products(also we can say projects) and these project work is done by the various depts.
*{color:#0000ff}Projects /Job table*
*--job_id*
*--Project_name*
*--Budget Amount{color}*
*{color:#0000ff}--Created a table for Project and department---RELATIONSHIP ---> proj_id and dept_id*
*--Also,Created a table for Project and Employee---RELATIONSHIP ---> proj_id and employee_id{color}*
Also,here scenario (1)Employees can work or be a part of many or multiple departments and work for multiple projects/products at a time (2)As usual-each Department has a manager.**EVery dept can handle or work only on one project.
*{color:#0000ff}--Created a table for Project and department---RELATIONSHIP ---> proj_id and dept_id*
*--Also,Created a table for Project and Employee---RELATIONSHIP ---> proj_id and employee_id*
*{color}*
_*{color:#000000}***(1)Are the tables and the relationships defined above enough or have i created too much tables?Please advise me.{color}*_
Queries:-Need to write SQLs for below items.Please help me.Could you all have a look
bq. h5. {color:#0000ff} \\ _ (2)SQL for a person see all his manager?***A person can have 2,3 managers._ \\ _ (3)need a person--->manager-->and their manager's MANAGER_ \\ _ (4)How will managers to view all employees reporting to him._ \\ {color} \\ h5. \\ {color:#0000ff}_(5)feasibility (SQL) to support the increase of salaries of employees in a department by percentage or amount wise._ \\ _ (6)SQL to update or change manager of a department/employee._ \\ {color} \\ h5. \\ {color:#0000ff}_(7)If a employee is removed-then all related details should also be removed._ \\ _ (8)to remove person and department,terminate a person from organisation_ \\ _ SHIFTING a person to different department,assign a person to a department_{color} \\ h5. {color:#0000ff}_SQL to collect all info of a person, his managers , departments and project this employee works._ \\ _ find Department which dont have managers._{color} \\ h5. \\ {color:#0000ff}_****find expenditure all projects together in terms of salary_{color}Sorry for all the confusion with the questions.So let me clear myself,i am doing this not as assignment or homework,but something
which interests me and trying to leran.Earlier as I stated that its a part of my school(** well frnakly speaking, it was my plan if i could
put this as an item of the school as the scope is very huge.
*(1)one employee can be in many departments(1 TO MANY) and and each department has one manager.(1 to 1)*
Created a table for EMPLOyee and department-RELATIONSHIP ---> empl_id and dept_id*
(2)Also,an employee can work in multiple items/projects(1-MANY) at a time. And a project HAS only one department.(1 to 1)
**Projects table created has codes,the Project name ,Planned budget cost/amount, start_date and end_date AND DEPART_ID
Also,Created a table for Project and Employee-RELATIONSHIP ---> proj_id and employee_id*
This is the full scenario has put above.So,i needed help as I am very confused if i have done the correct relationships.
And,these below items are my plans to allow the schema nd tables support it.
(2)how will a person see all his manager?***A person can have 2,3 managers.(EMP->MANAGER relationship TABLE)
(3)SQL to be able to show a person--->manager-->and their manager's MANAGER
(4)How will managers to view all employees reporting to him.
(5)SQL to support the increase of salaries of employees in a department by percentage or amount wise.
(6)SQL to update or change manager of a department/employee.
(7)If a employee is removed-then all related details should also be removed.
(8)to remove person and department,terminate a person from organisation
SHIFTING a person to different department,assign a person to a department
Projects /Job table EMPLOYEES TABLE-> SALARY info
--job_id
--Project_name
--Budget Amount -
SELECT, hierarchical queries and JOIN
Hi everyone,
I have a small SELECT statement but I can't find an easy solution.
Look at this situation:
drop table departments;
CREATE TABLE departments
dpt_id NUMBER(10) UNIQUE,
dpt_name VARCHAR2(100),
dpt_parent_id NUMBER(10)
TRUNCATE table departments;
INSERT INTO departments VALUES(1, 'Company', null);
INSERT INTO departments VALUES(2, 'HR', 1);
INSERT INTO departments VALUES(3, 'SALES', 1);
INSERT INTO departments VALUES(4, 'IT', 1);
INSERT INTO departments VALUES(222, 'Helpdesk', 4);
INSERT INTO departments VALUES(223, 'French Speaking', 222);
INSERT INTO departments VALUES(224, 'Another level', 223);
INSERT INTO departments VALUES(5, 'LEGAL', 1);
INSERT INTO departments VALUES(66, 'Recruitment', 2);
INSERT INTO departments VALUES(33, 'Logistics', 2);
INSERT INTO departments VALUES(39, 'Fleet management', 33);
INSERT INTO departments VALUES(31, 'Local Sales', 3);
INSERT INTO departments VALUES(60, 'European Sales', 3);
INSERT INTO departments VALUES(61, 'Germany', 60);
INSERT INTO departments VALUES(62, 'France', 60);
INSERT INTO departments VALUES(620, 'Paris', 62);
INSERT INTO departments VALUES(621, 'Marseilles', 62);
INSERT INTO departments VALUES(38, 'American Sales', 3);
INSERT INTO departments VALUES(34, 'Asian Sales', 3);
CREATE table persons
person_id NUMBER(10) UNIQUE,
person_name VARCHAR2(100),
person_dpt_id NUMBER(10)
truncate table persons;
INSERT INTO persons VALUES(1, 'Jim', 2);
INSERT INTO persons VALUES(2, 'Jack', 621);
INSERT INTO persons VALUES(3, 'John', 620);
INSERT INTO persons VALUES(4, 'John', 224);
INSERT INTO persons VALUES(5, 'Fred', 61);It's a simple hierachy like the one we can find in HR schema. The link between an department and its parent is with parent id. THe following statement build the whole tree:
SELECT dpt_id, level, LPAD(' ', LEVEL-1)|| dpt_name
FROM departments
START WITH dpt_parent_id IS NULL
CONNECT BY dpt_parent_id = PRIOR dpt_id;As you can see in the script above, I have a few people assigned to these departments. It's also a classic situtation...
I would like to have something like this:
WITH temp AS
SELECT dpt_id, dpt_name, SYS_CONNECT_BY_PATH(dpt_name, '#') as full_path
FROM departments
START WITH dpt_parent_id IS NULL
CONNECT BY dpt_parent_id = PRIOR dpt_id
SELECT p.person_name, d.dpt_name, --d.full_path,
regexp_substr(d.full_path, '[^#]+', 1, 2, 'i') as t1,
regexp_substr(d.full_path, '[^#]+', 1, 3, 'i') as t2,
regexp_substr(d.full_path, '[^#]+', 1, 4, 'i') as t3,
regexp_substr(d.full_path, '[^#]+', 1, 5, 'i') as t4
FROM persons p
JOIN temp d ON d.dpt_id = p.person_dpt_id;This is the exact output I want, but I wonder... Is it possible to do it without the factored sub-query? It's nice and works fine but I had to precompute the whole path to split it again. I mean, this should be possible in one step. Any suggestion?
I'm using Oracle 10g
Thanks,Hi,
user13117585 wrote:
... But sometimes, I just find the statements difficult for what they do. For example, my previous one. I have a person, and I want to see his department and the path in the tree.Actually, you want more than that; you want to parse the path, and display each #-delimited part in a separate column. If you didn't want that, then you could do away with the 4 REGEXP_SUBSTR calls, like this:
WITH temp AS
SELECT dpt_id, dpt_name
, SUBSTR ( REPLACE ( SYS_CONNECT_BY_PATH ( RPAD (dpt_name, 15) -- Using 15 just for demo
, 16
) as full_path
FROM departments
START WITH dpt_parent_id IS NULL
CONNECT BY dpt_parent_id = PRIOR dpt_id
SELECT p.person_name, d.dpt_name, d.full_path
FROM persons p
JOIN temp d ON d.dpt_id = p.person_dpt_id;Output:
PERSON_N DPT_NAME FULL_PATH
Jim HR HR
Fred Germany SALES European Sales Germany
John Paris SALES European Sales France Paris
Jack Marseilles SALES European Sales France Marseilles
John Another level IT Helpdesk French SpeakingAnother levelAs you can see, full_path is one giant column, but it's formatted to look like 4 separate columns, forresponding to your original t1, t2, t3 and t4. I limited the output to 15 characters, just for debugging and posting purposes. You can use any number of characters you like.
It's too complex for this simple thing.It would be nice if there was something simpler that did exactly what you wanted, but I'm not sure it's reasonable to expect it in every case. I asked a lot of questions in my first message, but I'm not sure you've tried to answer any of them, so I'm not sure why you're unhappy with the query you posted. I can think of lots of ways to change the query, but I have no way of telling if you would like them any better than what you already have.
And hopefully, I know where to start in the hierarchy and I know where to stop. If I had to show all the levels and have one column by level dynamically, I'd be stuck. Sorry, I don't understand this part.
Are you saying that it seems inefficient to generate the entire tree, when perhaps few of the nodes will have have matches in the persons table? If so, you can invert the whole query. Instead of doing the CONNECT BY first and then joining, do the join first and then the CONNECT BY. Instead of doing a top-down CONNECT BY, where you start with the parentless nodes (whether or not you'll ultimately need them) and then find their descendants, do a bottom-up CONNECT BY, where you start with the nodes you know you'll need, and then find their ancestors.
I just find it difficult for such a simple need. Again, there are lots of things that could be done. If you won't say what you want, that makes it hard for me to tell you how to get it. All that I've picked up for sure is that you don't like doing a sub-query. That's unfortunate, because sub-queries are so basic. They have very important been since Oracle 8.1, and they don't seem to be going away. Quite the opposite, in fact. You need sub-queries for all kinds of things, not just CONNECT BY. To give just a couple of examples, they're the only thing that make analytic functions really useful, and they simplfy chasm traps (basically, multiple 1-to-many relationships on the same table) considerably. I'm sorry if you don't lke sub-queries, but I don't see how you can work in this field and not use them.
Edited by: Frank Kulash on Nov 15, 2011 3:18 PM
Revised query
Maybe you are looking for
-
Problem with reminder after upgrading to ios5
Hi, My name is Henri and I'm from France. Excuse me first if the question had been asked, I didn't found any answer to my research. I upgraded my iphone 4 to ios 5 yesterday and since there I couldn't use my reminder, because the plus signe didn't ap
-
How do i back-up my music to cds?
According to the directions, I should find a link under File -> Library -> back-up on iTunes. I can't find an option for backing up anywhere. I would like to back-up my music to cds.
-
Hi I'm just wondering if it will be ok and not cause any problems. So basically I have sold my old laptop that I used to sync my iPhone with. Yes I wiped the computer before it left. So my main question is when I have a brand new laptop now will my p
-
Notes does not snyc from Icould to Iphoen 4s in either direction
Notes does not snyc from Icould to Iphoen 4s in either direction what a piece of crap, this feature has never worked for me, ALSO I can't backup Notes in Itunes (I'm using Itunes for windows)
-
Just thought I'd share. :)