Oracle 19c SQL

  1. Home
  2. Docs
  3. Oracle 19c SQL
  4. 8 Hierarchical Query
  5. 8.2 Hierarchical Functions

8.2 Hierarchical Functions

Oracle provides following functions to deal with hierarchical queries.

Functions

  • CONNECT_BY_ROOT : Returns the root node(s) associated with the current row.
  • SYS_CONNECT_BY_PATH : Returns a delimited breadcrumb from root to the current row

CONNECT_BY_ROOT

CONNECT_BY_ROOT is a unary operator that is valid only in Hierarchical queries. We should qualify a column with this operator, then Oracle returns the column value using data from the root row. Qualifying column in CONNECT_BY_ROOT in parenthesis is not mandatory, but it is good to do so. CONNECT_BY_ROOT extends the functionality of the CONNECT BY [PRIOR] condition of hierarchical query.

SELECT Ename, Job, CONNECT_BY_ROOT(Ename) Boss
  FROM Emp
 START WITH Job = 'PRESIDENT'
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB       BOSS
---------- --------- ----------
KING       PRESIDENT KING 
JONES      MANAGER   KING 
SCOTT      ANALYST   KING 
ADAMS      CLERK     KING 
FORD       ANALYST   KING 
SMITH      CLERK     KING 
CLARK      MANAGER   KING 
MILLER     CLERK     KING 
BLAKE      MANAGER   KING 
ALLEN      SALESMAN  KING 
WARD       SALESMAN  KING 
MARTIN     SALESMAN  KING 
TURNER     SALESMAN  KING 
JAMES      CLERK     KING 

14 rows selected.
SELECT Ename, Job, CONNECT_BY_ROOT(Ename) Boss
  FROM Emp
 START WITH Ename = 'JONES'
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB       BOSS  
---------- --------- ----------
JONES      MANAGER   JONES
SCOTT      ANALYST   JONES
ADAMS      CLERK     JONES
FORD       ANALYST   JONES
SMITH      CLERK     JONES
SELECT Ename, Job, CONNECT_BY_ROOT(Ename) Boss
  FROM Emp
 START WITH Job = 'MANAGER'
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB       BOSS
---------- --------- ----------
JONES      MANAGER   JONES 
SCOTT      ANALYST   JONES 
ADAMS      CLERK     JONES 
FORD       ANALYST   JONES 
SMITH      CLERK     JONES 
CLARK      MANAGER   CLARK 
MILLER     CLERK     CLARK 
BLAKE      MANAGER   BLAKE 
ALLEN      SALESMAN  BLAKE 
WARD       SALESMAN  BLAKE 
MARTIN     SALESMAN  BLAKE 
TURNER     SALESMAN  BLAKE 
JAMES      CLERK     BLAKE 

13 rows selected.

Q : Get the employee name, job, salary with the organization head name, salary and how much less the employees are paid compared to the organization head?

Ans:

SELECT 
      Ename, 
      Job, 
      Sal,
      CONNECT_BY_ROOT Ename BOSS,
      CONNECT_BY_ROOT Sal "BOSS SALARY",
      CONNECT_BY_ROOT Sal - Sal "SALARY DIFF"
  FROM Emp
 START WITH Empno = 7839
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB              SAL BOSS       BOSS SALARY SALARY DIFF 
---------- --------- ---------- ---------- ----------- ----------- 
KING       PRESIDENT       5000 KING              5000           0 
JONES      MANAGER         2975 KING              5000        2025 
SCOTT      ANALYST         3000 KING              5000        2000 
ADAMS      CLERK           1100 KING              5000        3900 
FORD       ANALYST         3000 KING              5000        2000 
SMITH      CLERK            800 KING              5000        4200 
CLARK      MANAGER         2450 KING              5000        2550 
MILLER     CLERK           1300 KING              5000        3700 
BLAKE      MANAGER         2850 KING              5000        2150 
ALLEN      SALESMAN        1600 KING              5000        3400 
WARD       SALESMAN        1250 KING              5000        3750 
MARTIN     SALESMAN        1250 KING              5000        3750 
TURNER     SALESMAN        1500 KING              5000        3500 
JAMES      CLERK            950 KING              5000        4050 

14 rows selected.

Q : Get the employee name, job, joining date with the organization head name, joining date and how much experience difference the employees have with respect to the organization head?

Ans:

SELECT
      Ename, 
      Job, 
      HireDate JoinDate,
      CONNECT_BY_ROOT(Ename) Boss,
      CONNECT_BY_ROOT(HireDate) "BOSS JOINDATE",
      RTRIM(ROUND(MONTHS_BETWEEN(CONNECT_BY_ROOT(HireDate), HireDate)/ 12, 1)||' Yrs', 8) "EXP DIFF"
  FROM Emp
 START WITH Sal = 5000
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB       JOINDATE  BOSS       BOSS JOINDATE EXP DIFF
---------- --------- --------- ---------- ------------- ------------
KING       PRESIDENT 17-NOV-81 KING           17-NOV-81 0 Yrs
JONES      MANAGER   02-APR-81 KING           17-NOV-81 .6 Yrs
SCOTT      ANALYST   19-APR-87 KING           17-NOV-81 -5.4 Yrs
ADAMS      CLERK     23-MAY-87 KING           17-NOV-81 -5.5 Yrs
FORD       ANALYST   03-DEC-81 KING           17-NOV-81 0 Yrs
SMITH      CLERK     17-DEC-80 KING           17-NOV-81 .9 Yrs
CLARK      MANAGER   09-JUN-81 KING           17-NOV-81 .4 Yrs
MILLER     CLERK     23-JAN-82 KING           17-NOV-81 -.2 Yrs
BLAKE      MANAGER   01-MAY-81 KING           17-NOV-81 .5 Yrs
ALLEN      SALESMAN  20-FEB-81 KING           17-NOV-81 .7 Yrs
WARD       SALESMAN  22-FEB-81 KING           17-NOV-81 .7 Yrs
MARTIN     SALESMAN  28-SEP-81 KING           17-NOV-81 .1 Yrs
TURNER     SALESMAN  08-SEP-81 KING           17-NOV-81 .2 Yrs
JAMES      CLERK     03-DEC-81 KING           17-NOV-81 0 Yrs

14 rows selected.

Q : Get the details of the employees who have joined before the organization head?

Ans:

SELECT 
      Ename,
      Job,
      HireDate JoinDate,
      CONNECT_BY_ROOT(Ename) Boss,
      CONNECT_BY_ROOT(HireDate) "BOSS JOINDATE",
      RTRIM(ROUND(MONTHS_BETWEEN(CONNECT_BY_ROOT(HireDate), HireDate), 1)||' Months', 12) "EXP DIFF"
  FROM Emp
 WHERE SIGN(MONTHS_BETWEEN(CONNECT_BY_ROOT(HireDate), HireDate)) = 1
 START WITH Sal = 5000
CONNECT BY PRIOR Empno = Mgr;

ENAME      JOB       JOINDATE  BOSS       BOSS JOINDATE EXP DIFF
---------- --------- --------- ---------- ------------- ------------
JONES      MANAGER   02-APR-81 KING           17-NOV-81 7.5 Months
SMITH      CLERK     17-DEC-80 KING           17-NOV-81 11 Months
CLARK      MANAGER   09-JUN-81 KING           17-NOV-81 5.3 Months
BLAKE      MANAGER   01-MAY-81 KING           17-NOV-81 6.5 Months
ALLEN      SALESMAN  20-FEB-81 KING           17-NOV-81 8.9 Months
WARD       SALESMAN  22-FEB-81 KING           17-NOV-81 8.8 Months
MARTIN     SALESMAN  28-SEP-81 KING           17-NOV-81 1.6 Months
TURNER     SALESMAN  08-SEP-81 KING           17-NOV-81 2.3 Months

8 rows selected.

SYS_CONNECT_BY_PATH

Display the full path from the current row to its root.

--Get path from top to bottom for PRESIDENT

SELECT Ename, SYS_CONNECT_BY_PATH(Ename, '/') Path
  FROM Emp
 START WITH Job = 'PRESIDENT'
CONNECT BY PRIOR Empno = Mgr;

NAME       PATH
---------- ------------------------------
KING       /KING
JONES      /KING/JONES
SCOTT      /KING/JONES/SCOTT
ADAMS      /KING/JONES/SCOTT/ADAMS
FORD       /KING/JONES/FORD
SMITH      /KING/JONES/FORD/SMITH
CLARK      /KING/CLARK
MILLER     /KING/CLARK/MILLER
BLAKE      /KING/BLAKE
ALLEN      /KING/BLAKE/ALLEN
WARD       /KING/BLAKE/WARD
MARTIN     /KING/BLAKE/MARTIN
TURNER     /KING/BLAKE/TURNER
JAMES      /KING/BLAKE/JAMES

14 rows selected.
--Get path from bottom to top for SMITH

SELECT Ename, SYS_CONNECT_BY_PATH(Ename, '/') Path
  FROM Emp
 START WITH Ename = 'SMITH'
CONNECT BY Empno = PRIOR Mgr;

ENAME      PATH
---------- ------------------------------
SMITH      /SMITH
FORD       /SMITH/FORD
JONES      /SMITH/FORD/JONES
KING       /SMITH/FORD/JONES/KING

Q : Get the hierarchy of every job in the organization?

Ans:

SELECT DISTINCT Job, SYS_CONNECT_BY_PATH(Job, '/') Path
  FROM Emp
 START WITH Empno = 7839
CONNECT BY PRIOR Empno = Mgr;

JOB       PATH
--------- --------------------------------------------------
PRESIDENT /PRESIDENT
CLERK     /PRESIDENT/MANAGER/ANALYST/CLERK
SALESMAN  /PRESIDENT/MANAGER/SALESMAN
CLERK     /PRESIDENT/MANAGER/CLERK
ANALYST   /PRESIDENT/MANAGER/ANALYST
MANAGER   /PRESIDENT/MANAGER

6 rows selected.
Was this article helpful to you? Yes No

How can we help?