tree structure oracle sql [duplicate] - sql

This question already has answers here:
SQL Tree Structure
(4 answers)
Closed 6 months ago.
I would like to show employees hierarchy in tree structure.
I have this table.
Employee
-------------
EMP_ID (Number)
JOB_ID (Number)
Manager_ID (Number)
Effective_from (Date)
Effective_to (Date)
EMP_ID represents the Manager employee has. I would like to show the whole tree structure of Managers.
Table for reference.
EMP_FIRST_NAME JOB_DESCRIPTION MANAGER EFFECTIVE_F EFFECTIVE_T
--------------- -------------------- ---------- ----------- -----------
Tomm General Manager 01-jan-2000 01-jan-3000
Mohammed Senior Accountant Tomm 01-jan-2000 01-jan-3000
Ali Accountant Tomm 01-jan-2000 01-jan-3000
Basel Accountant Mohammed 01-jan-2000 01-jan-3000

This is a classic hierarchical query; demonstrated on Scott's EMP table:
SQL> select * From employee;
EMP_ID EMPLOYEE_N JOB MANAGER_ID
---------- ---------- --------- ----------
7369 SMITH CLERK 7902
7499 ALLEN SALESMAN 7698
7521 WARD SALESMAN 7698
7566 JONES MANAGER 7839
7654 MARTIN SALESMAN 7698
7698 BLAKE MANAGER 7839
7782 CLARK MANAGER 7839
7788 SCOTT ANALYST 7566
7839 KING PRESIDENT
7844 TURNER SALESMAN 7698
7876 ADAMS CLERK 7788
7900 JAMES CLERK 7698
7902 FORD ANALYST 7566
7934 MILLER CLERK 7782
14 rows selected.
You'd then
SQL> select lpad(employee_name, 2 * (level + 1), ' ') name
2 from employee e
3 start with manager_id is null
4 connect by prior emp_id = manager_id;
NAME
--------------------------------------------------------------------------------
KING
JONES
SCOTT
ADAMS
FORD
SMITH
BLAKE
ALLEN
WARD
MARTIN
TURNER
JAMES
CLARK
MILLER
14 rows selected.
SQL>

Related

Why versions_xid value gets reset after some time in Oracle?

While working with row versions query it has been observed the versions_xid value gets removed after some time.
For example:
SQL> select versions_xid, empno, ename, sal from scott.emp
versions between scn minvalue and maxvalue
order by sal;
VERSIONS_XID EMPNO ENAME SAL
---------------- ---------- ---------- ----------
7369 SMITH 800
7900 JAMES 950
7876 ADAMS 1100
7521 WARD 1250
7654 MARTIN 1250
7934 MILLER 1300
7839 KING 1400
7788 SCOTT 1400
7844 TURNER 1500
01002100D6050000 7788 SCOTT 1500
7499 ALLEN 1600
7566 JONES 1800
0800130073070000 7788 SCOTT 1800
06001500DB070000 7788 SCOTT 1900
04000C00B9060000 7788 SCOTT 2000
7782 CLARK 2450
7698 BLAKE 2850
7902 FORD 3000
18 rows selected.
SQL>
After some time when i execute the same query the row versions are gone!
SQL> select versions_xid, empno, ename, sal from scott.emp
versions between scn minvalue and maxvalue
order by sal; 2 3
VERSIONS_XID EMPNO ENAME SAL
---------------- ---------- ---------- ----------
7369 SMITH 800
7900 JAMES 950
7876 ADAMS 1100
7521 WARD 1250
7654 MARTIN 1250
7934 MILLER 1300
7839 KING 1400
7844 TURNER 1500
7499 ALLEN 1600
7566 JONES 1800
7788 SCOTT 2000
7782 CLARK 2450
7698 BLAKE 2850
7902 FORD 3000
14 rows selected.
SQL>
Can someone please let me know whats happening? Is it something to do with undo_retention? Because, reading through various blogs and Oracle docs didn't give a direct answer or relation.

SQL*Plus column separator

I'm in scott user in SQL*Plus and is it possible in this select to separate columns by tabulation instead of the default space?
SELECT empno, ename, job FROM emp
Unfortunately this doesn't work:
SELECT empno '\t', ename '\t', job '\t' FROM emp
Instead of:
EMPNO ENAME JOB
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7654 MARTIN SALESMAN
7698 BLAKE MANAGER
7782 CLARK MANAGER
7839 KING PRESIDENT
7844 TURNER SALESMAN
7900 JAMES CLERK
7902 FORD ANALYST
7934 MILLER CLERK
I want more space between columns:
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7566 JONES MANAGER
7654 MARTIN SALESMAN
7698 BLAKE MANAGER
7782 CLARK MANAGER
7839 KING PRESIDENT
7844 TURNER SALESMAN
7900 JAMES CLERK
7902 FORD ANALYST
7934 MILLER CLERK
Use the COLUMN command (see SQL*PlusĀ® User's Guide and Reference) and format your report according your wish
An easier solution would be:
set colsep ' '
As sqlab already pointed out you need the COLUMN formatting options which are in SQL*PLUS.
Since the docs aren't very readable, here is what you need:
COLUMN EMPNO FORMAT A10
COLUMN ENAME FORMAT A16
COLUMN JOB FORMAT A9
If you need to do it in regular SQL you can use this:
SELECT rpad(empno, ' ', 11) empno
, rpad(ename, ' ', 17) ename
, job
FROM emp

In what order distinct clause with one column(say) displays the output in oracle? [duplicate]

This question already has answers here:
Default row ordering for select query in oracle
(8 answers)
Closed 9 years ago.
EMP table
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 Smith Clerk 7902 12/17/1980 800 30
7499 Allen Salesman 7698 2/20/1981 1600 300 30
7521 Ward Salesman 7698 2/22/1981 1250 500 30
7566 Jones Manager 7839 4/2/1981 2975 20
7654 Martin Salesman 7698 9/28/1981 1250 1400 30
7698 Blake Manager 7839 5/1/1981 2850 30
7782 Clark Manager 7839 6/9/1981 2450 10
7788 Scott Analyst 7566 12/9/1982 3000 20
7839 King President 11/17/1981 5000 10
7844 Turner Salesman 7698 9/8/1981 1500 30
7876 Adams Clerk 7788 1/12/1983 1100 20
7900 James Clerk 7698 12/3/1981 950 30
7902 Ford Analyst 7566 12/3/1981 3000 20
7934 Miller Clerk 7782 1/23/1982 1300 10
Suppose we executed the following query on the above table:
select distinct ename from emp;
Output
ENAME
Ward
Turner
Adams
Allen
Martin
Blake
Clark
Scott
Ford
King
Miller
Jones
Smith
James
Now anyone Please explain me why Ward is displayed as output in the 1st row and not in the order of the table output format??
Because you have to specify an order
select distinct ename
from emp
order by ename
If you don't then the DB will grab the records in the name of performance and output it unordered.
Without ordering how you can expect ordered result.Use order by clause.

how i can display data like displayed below from two tables [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to display data from two tables, employee and department. It must display department detail then all employees related to that department. This is how I want to display:
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
EMPNO ENAME
---------- ----------
7782 CLARK
7839 KING
7934 MILLER
20 RESEARCH DALLAS
EMPNO ENAME
---------- ----------
7369 SMITH
7566 JONES
7788 SCOTT
7876 ADAMS
7902 FORD
30 SALES CHICAGO
EMPNO ENAME
---------- ----------
7499 ALLEN
7521 WARD
7654 MARTIN
7698 BLAKE
7844 TURNER
7900 JAMES
APPENDIX
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10
SQL is designed to retrieve set based raw data, not present it in that kind of format. The best you can do is get the data in the right order -
SELECT
DEPTNO,
DEPT.LOC,
EMPNO,
ENAME
FROM EMP INNER JOIN DEPT
ON EMP.DEPTNO=DEPT.KEY-FIELD
ORDER BY 1,3
.. and then use some report tool to break it up into sections.
(and I hope that's dummy test data, not real salary info :)

COUNT is incorrect when grouping?

I am trying to display the employee number of each employee who manages other employees with the number of people he or she manages with the below table called emp.
empno ename job mgr hiredate sal comm deptno
----- ------ ---------- ---------- ---------- ------- ------- ------
7369 Smith Clerk 7902 1980-12-17 800 20
7499 Allen Salesman 7698 1981-02-20 1600 300 30
7521 Ward Salesman 7698 1981-02-22 1250 500 30
7566 Jones Manager 7839 1981-04-02 2975 20
7654 Martin Salesman 7698 1981-09-28 1250 1400 30
7698 Blake Manager 7839 1981-05-01 2850 30
7782 Clark Manager 7839 1981-06-09 2450 10
7788 Scott Analyst 7566 1982-12-09 3000 20
7839 King President 1981-11-17 5000 10
7844 Turner Salesman 7698 1981-09-08 1500 0 30
7876 Adams Clerk 7788 1983-01-12 1100 20
7900 James Clerk 7698 1983-12-03 950 30
7902 Ford Analyst 7566 1983-12-13 3000 20
7934 Miller Clerk 7782 1982-01-23 1300
Any idea of how I can go about doing this?
I have tried
select empno,count(mgr) from emp group by empno,mgr;
but this returns:
empno count(mgr)
---------- ----------
7369 1
7499 1
7521 1
7566 1
7654 1
7698 1
7782 1
7788 1
7839 0
7844 1
7876 1
7900 1
7902 1
7934 1
Thanks so much for your help.
select count(*) from employee_table group by mgr
I would actualy group by mgr, then you'd have a group per manager and can just do a count to see how many persons that manager manages. Then, you could do a self join on the table to get that manager's info. Something like:
SELECT E1.Mgr, E2.ename, Count(*) as Number FROM Employees E1
INNER JOIN Employees E2 ON E1.mgr = E2.empno
GROUP BY E1.Mgr
Though I haven't tested this.
You can try these that do not use join:
select mgr, count(eno)
from employee
group by mgr
or
select name, e1.mgr, count(e1.eno)
from employee e1
group by rollup (e1.mgr, name)