hierarchy level in relationship table in oracle - oracle

I have a table employee which has hierarchy data of manager and employee.
Sample data.
empId ManId
101 100
102 100
1010 101
1011 101
10101 1010
I need to find the level but it is not giving me correct output. I need an output like
level Emp ID Man Id
1 101 100
1 102 100
2 1010 101
2 1011 101
3 10101 1010
Irrespective of the input as Emp ID or Man ID, the output should be constant. I am only getting the output when I am using manager id as 100 but it doesnt work when i pass value as 10101
select distinct
level,
manager_id,
employee_id
from employees
START WITH manager_id = 100
connect by manager_id= prior employee_id
order by level

START WITH clause is used to specify a root row for the hierarchy which is employee id with 101 value
Kindly use the below
select distinct
level,
manager_id,
employee_id
from employees
where level<=3
START WITH employee_id = 101
connect by manager_id= prior employee_id
order siblings by employee_id
Update1:-:-You can remove START WITH if root row is not specific
select distinct
level,
manager_id,
employee_id
from employees
where level<=3
connect by manager_id= prior employee_id
order siblings by employee_id
Check this link for more information
Hierarchical Queries

Related

Count Different Values in Oracle Using Outer Joins

My question is about left outer join with counter. I have two tables.
employee:
empid empname
----- -------
101 Tom
102 Jerry
103 Jack
104 Tim
allocation:
generator analyzer tester
--------- -------- ------
101 102 103
103 102 101
102 101 104
I need following result
empid empname generator analyzer tester
------ ------- --------- -------- -------
101 Tom 1 1 1
102 Jerry 1 2 0
103 Jack 1 0 1
104 Tim 0 0 1
I need to count the values of each task. Tom has generated 1, analyzed 1
and tested 1. Like that i need to count the values. Is this possible in
SQL. If this is possible please help me to get output.
I am getting the result. but it is not expected. I have used outer joins to solve the problem,
select
e.empid,
e.empname,
count(a1.generator),
count(a2.analyzer),
count(a3.tester)
from employee e
left join allocation a1
on e.empid=a1.author
left join allocation a2
on e.empid=a2.reviewer
left join allocation a3
on e.empid=a3.tester
group by
e.empid,
e.empname;
You can achieve it with this:
Select empid,sum(generaor),sum(analyzer),sum(tester)
from
(
Select empid,count(a.generaor) generaor,0 analyzer,0 tester
from employee
JOIN Allocation a on empid=a.generaor group by empid,a.generaor
UNION
Select empid,0 generaor,count(b.analyzer)analyzer,0 tester
from employee
JOIN Allocation b on empid=b.analyzer group by empid,b.analyzer
UNION
Select empid,0 generaor,0 analyzer,count(c.tester) tester
from employee
JOIN Allocation c on empid=c.tester group by empid,c.tester
) stag
group by empid
Try this
SELECT empid, empname, sum(generator), sum(analyzer), sum(tester) FROM
(SELECT e.empid, e.empname, count(a1.generator) generator, 0 analyzer, 0 tester
FROM Employee e
JOIN Allocation a1 ON a1.generator = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, count(a2.analyzer) analyzer, 0 tester
FROM Employee e
JOIN Allocation a2 ON a2.analyzer = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, 0 analyzer, count(a3.tester) tester
FROM Employee e
JOIN Allocation a3 ON a3.tester = e.empid
GROUP BY e.empname) tmp
GROUP BY empname
ORDER BY empid

Value Set in Oracle Apps using Union

I need to create a value set which selects items from a custom table for certain run no and union it with Select 'ALL' from dual so that when the user selects ALL the program runs for all the items.
I tried creating a view of the custom table and then used
select item from xx_cust_view where run_no=:$FLEX$.RUN_NO_VS union select 'ALL' from dual
It is saved without error in value set but gives an error when I try to pass values while running the program.
Please suggest.
I don't know Oracle Apps. but I thought that the following example might give you an idea.
It is ran in SQL*Plus, based on HR's departments table. Parameter PAR_DNAME accepts either real department name (such as "Purchasing") or ALL (which is then supposed to return all departments). ROWNUM is here just to restrict number of returned rows (so that I wouldn't display all 27 departments).
Have a look:
SQL> select * from departments
2 where department_name =
3 case when '&&par_dname' = 'ALL' then department_name
4 else '&&par_dname'
5 end
6 --
7 and rownum <= 5;
Enter value for par_dname: Purchasing
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
------------- ------------------------------ ---------- -----------
30 Purchasing 114 1700
SQL> undefine par_dname
SQL> /
Enter value for par_dname: ALL
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
------------- ------------------------------ ---------- -----------
10 Administration 200 1700
20 Marketing 201 1800
30 Purchasing 114 1700
40 Human Resources 203 2400
50 Shipping 121 1500
SQL>
Value set does not allow union, group by .
So i created a view of the union query and used this view in the value set to fetch the values.

Problems using GROUP BY and ORDER BY in SQL Oracle

So I've been instructed to write a SQL query to display the manager number and the salary of the lowest paid employee for that manager(2 columns within a database I'm working in). I must also exclude any groups where the minimum
salary is less than or equal to $6,000. Sort the output in descending order of
salary. Now I've successfully displayed the data however, I cannot seem to order it in descending order which is what brought me here. Currently my code is as follows:
Code Snippet #1
SELECT manager_id AS "Manager ID",
MIN(salary) AS "Lowest Paid Salary"
FROM employees
WHERE manager_id IS NOT NULL
AND salary > 6000
GROUP BY manager_id;
Which gives me the following output:
Code Snippet #2
Manager ID Lowest Paid Salary
---------- ------------------
100 6500
147 6200
205 8300
108 6900
148 6100
149 6200
102 9000
101 6500
145 7000
146 7000
However, I need these values ordered from Largest -> Smallest salary. I attempted to add a GROUP BY salary DESC; At the end of the statement which would give me the following error: ORA-00979: not a GROUP BY expression
Upon some research I found that the two (GROUP BY and ORDER BY) cannot be used together in the same query as I did not include both manager_id and salary within the GROUP BY clause. So I attempted that with the following code:
SELECT manager_id AS "Manager ID",
MIN(salary) AS "Lowest Paid Salary"
FROM employees
WHERE manager_id IS NOT NULL
AND salary > 6000
GROUP BY manager_id, salary
ORDER BY salary DESC;
Which gives me a list of all the salaries for each manager_id as well as duplicates. This is not what I am looking for.
I apologize for the excess of reading, I just want to make sure you know what I've tried and what I am attempting to accomplish.
So I need to know a way I can either use both the GROUP BY and ORDER BY in the same query to display the Code snippet #2 but have it ordered. Or another way to order this data in the same format.
Thanks in advance for any help/advice.
You can either sort by the column number or column name
SELECT manager_id AS "Manager ID",
MIN(salary) AS "Lowest Paid Salary"
FROM #employees
WHERE manager_id IS NOT NULL
AND salary > 6000
GROUP BY manager_id
order by 2 desc
SELECT manager_id AS "Manager ID",
MIN(salary) AS "Lowest Paid Salary"
FROM #employees
WHERE manager_id IS NOT NULL
AND salary > 6000
GROUP BY manager_id
order by "Lowest Paid Salary" desc
You need to order by the aggregate function. ...
Try this
SELECT manager_id AS "Manager ID",
MIN(salary) AS "Lowest Paid Salary"
FROM employees
WHERE manager_id IS NOT NULL
AND salary > 6000
GROUP BY manager_id
ORDER BY min(salary) DESC;
Try:
order by manager_id ,salary DESC and remove the group by clause
for example
SELECT * FROM Customers
ORDER BY CustomerID DESC,CustomerName;
This statement will arrange the results according to customer id in desc order.

display manager name and count of employees reporting him in employees table

I want to display manager_name and count of employees reporting him in employees table.I want to sort the data based on count IE maximum employees reporting to a manager should come first.
I tried to write self join but i could not get the out put .
EMPLOYEE_ID FIRST_NAME MANAGER_ID SALARY HIRE_DATE
198 Donald 124 2600 21-JUN-99
199 Douglas 124 2600 13-JAN-00
200 Jennifer 101 4400 17-SEP-87
201 Michael 100 13000 17-FEB-96
202 Pat 201 6000 17-AUG-97
203 Susan 101 6500 07-JUN-94
204 Hermann 101 10000 07-JUN-94
205 Shelley 101 12000 07-JUN-94
206 William 205 8300 07-JUN-94
100 Steven 24000 17-JUN-87
101 Neena 100 17000 21-SEP-89
the table name is employees and i want to see names also
You can use the aggregate function COUNT and ORDER BY clause
You didn't mention the table name assuming the table name as EMPLOYEES, below query would help you.
SELECT MANAGER_ID, COUNT(EMPLOYEE_ID) as EMP_COUNT
FROM EMPLOYEES
GROUP BY MANAGER_ID
ORDER BY EMP_COUNT DESC;
Here EMP_COUNT is the column alias name.If you don't want any column alias you can simply use the query below.
SELECT MANAGER_ID, COUNT(EMPLOYEE_ID)
FROM EMPLOYEES
GROUP BY MANAGER_ID
ORDER BY COUNT(EMPLOYEE_ID) DESC;
If you want to sort by ascending order instead of DESC you can use ASC.
We can get this output using an analytical function:
SELECT E.EMPID,E.EMPNAME as "Manager Name",M.EMPNAME AS "Employee Name",count(*) over(partition by e.empid) reportee_count
from empmgid m,empmgid e where M.MAGID=e.EMPID order by reportee_count desc;
Please employ the following SQL-Query:
SELECT
e.empno,
e.ename,
e1.empcnt
FROM
emp e,
(
SELECT
mgr,
COUNT(*) empcnt
FROM
emp
GROUP BY
mgr
) e1
WHERE
e.empno = e1.mgr;
-- Restricting which manager is having two employees working under them
-----------------------------------------------------------------------
SELECT E1.* FROM
(
SELECT E1.EMPNO,E1.ENAME AS EMPLOYE,
M1.ENAME AS MANAGERS,
COUNT(*)
OVER
(
PARTITION BY E1.EMPNO
) EMPCNT
FROM EMP E1,EMP M1
WHERE M1.MGR=E1.EMPNO
) E1
WHERE EMPCNT = 2;
select count(distinct manager_id) from employees;
select count(distinct manager_id) from employees;
Ans:
COUNT(DISTINCTMANAGER_ID)
18

how to get dfferent values using the same ID in the mess table in oracle?

The table has single row with unique ID, duplicated rows and multiple different rows with the same ID.
I need to pick up those rows which have different values with the same ID
ID Major Major_ID
1234 chemi 1111
1234 chemi 1111
673 biology 2222
673 phylo 3333
2480 comput 4444
2480 busine 5555
243 accout 6666
492 finance 7777
4812 engine 8888
SQLFiddle with sample data: http://www.sqlfiddle.com/
The expected result:
ID Majoy Major_ID
673 biology 2222
673 phylo 3333
2480 comput 4444
2480 busine 5555
CREATE TABLE NEW_TABLE AS
SELECT ID,Majoy,Major_ID
FROM YOUR_TABLE T
WHERE NOT EXISTS (
select null
From YOUR_TABLE
WHERE T.ID=ID AND T.Majoy = Majoy and T.Major_ID = Major_ID
GROUP BY ID,Majoy,Major_ID
HAVING COUNT(*)>1
)
The subquery gets the duplicate data. Then i exclude these rows of the resultset with the principal query. The create table as statement creates a new table based on the data from the query like select into in sql server
You can use the COUNT as analytical function, to count the distinct majors for each id, and then select only those that have count more than 1.
SELECT id, major, major_id
FROM (SELECT id,
major,
major_id,
COUNT (DISTINCT major) OVER (PARTITION BY id) AS count_
FROM first_table)
WHERE count_ > 1;
Select Id, Major, Major_ID
from First_Table
Minus
Select Id, Major, Major_ID
from Second_Table

Resources