Given the following Table (In Postgres):
EmployeeID
EmployeeName
ManagerID
1
David
NULL
2
Jessica
NULL
3
Gregg
1
4
Joe
3
5
Brandon
NULL
6
Leslie
4
7
Harry
6
8
Paul
NULL
9
Frank
5
Starting from Employee ID 7 (Harry) - how do I list only the records, bottom-up, in the hierarchy until I get to the ultimate manager (which should be David, in this case)? Should I use recursive CTE? If so, how does that query look?
Expected Output:
EmployeeID
EmployeeName
ManagerID
1
David
NULL
3
Gregg
1
4
Joe
3
6
Leslie
4
7
Harry
6
In the common table expression, you can recognize:
the base step, where you select the record relatively to employee no 7
the recursive step, where you match managers with currently retrieved employees.
The recursion stops when the INNER JOIN does not return any more extra record.
WITH RECURSIVE cte AS (
SELECT * FROM tab WHERE EmployeeID = 7
UNION ALL
SELECT mgr.*
FROM cte emp
INNER JOIN tab mgr
ON emp.ManagerID = mgr.EmployeeID
)
SELECT *
FROM cte
Check the demo here.
Related
I want to join two tables and use the column they both share to group the results, including a null result for those accountIds which only appear in one table.
Table a
AccountId
productApurchases
Steve
1
Jane
5
Bill
10
Abed
2
Table b
AccountId
productApurchases
Allan
1
Jane
10
Bill
2
Abed
1
Mike
2
Desired output
AccountId
productApurchases
productBpurchases
Steve
1
0
Jane
5
10
Bill
10
2
Abed
2
1
Mike
0
2
I've been trying with various joins but cannot figure out how to group by all the account ids.
Any advice much appreciated, thanks.
Use full join:
select accountid,
coalesce(productApurchases, 0) as productApurchases,
coalesce(productBpurchases, 0) as productBpurchases
from a full join
b
using (accountid);
Suppose I have a table like below:
ID Name ManagerID
1 Dave NULL
2 Scott 1
3 Mike 1
4 Nick 3
5 Jack 1
How Can I find out corresponding Manager Name of all the employee, something like below format?
ID Name ManagerID ManagerName
1 Dave NULL NULL
2 Scott 1 Dave
3 Mike 1 Dave
4 Nick 3 Mike
5 Jack 1 Dave
Try this!
select a.ID,a.Name,a.ManagerID,b.Name as ManagerName
from #t a left join #t b on a.ManagerID=b.ID
Demo
select ID, Name, ManagerID,
(case when managerid is null then null else (select Name from tab where id=managerid) end) as ManagerName
from tab
You can do this way too
Possible in several ways.
Such as:
SELECT
ID, Name, ManagerID,
(SELECT Name FROM table AS ManagersTable WHERE ManagersTable.ID=EmployeesTable.ManagerID) AS ManagerName
FROM table AS EmployeesTable
I have a requirement in such a way that it should join two tables with more than 100k records in one table and just 5 records in another table as shown below
Employee Dept Result
id Name deptid deptid Name Name deptid Name
1 Jane 1 1 Science Jane 1 Science
2 Jack 2 2 Maths Dane 1 Science
3 Dane 1 3 Biology Jack 2 Maths
4 Drack 3 4 Social Drack 3 Biology
5 Drim 5 Zoology Kery 4 Social
6 Drum 5 Drum 5 Zoology
7 Krack
8 Kery 4
.
.
100k
Which join need to be used to get the query in an better way to perform to get the result as shown.
I just want the query to join with other table from employee table only which has dept which i thought of below query but wanted to know is there any better way to do it.
Select e.name,d.deptid,d.Name from
(Select deptid,Name from Employee where deptid IS NOT NULL) A
and dept d where A.deptid=d.deptid;
Firstly not sure why you are performing your query the way you are. Should be more like
SELECT A.name, D.deptid,D.Name
FROM Employee A
INNER JOIN dept D
ON A.deptid = D.deptid
No need of the IS NOT NULL statement.
If this is a ONE TIME or OCCASIONAL thing and performance is key (not a permanent query in your DB) you can leave out the join altogether and do it using CASE:
SELECT
A.name, A.deptid,
CASE
WHEN A.deptid = 1 THEN "Science"
WHEN A.deptid = 2 THEN "Maths"
...[etc for the other 3 departments]...
END as Name
FROM Employee A
If this is to be permanent and performance is key, simply try applying an INDEX on the foreign key deptid in the Employee table and use my first query above.
I am trying to select unique random posting/recruitment places of employees within a list of places, all the employees are already posted at the places, i am trying to generate a new random posting place for them with "where" condition that "employee new random location will not be equal to their home place"
Employee table is :
EmpNo Empname CurrentPosting Home Designation RandomPosting
1 Satish Kumar Samastipur Gazi Manager
2 Anil Kumar Singh Vaishali Patna Manager
3 Rajdev Prasad Nawada Gaya PO
4 Rajesh Kumar Sheikhpura Muzaffarpur PO
5 Jitendra Kumar Banka Bhagalpur Clerk
And so on...
And Places table is
PlaceID PlaceName Manager PO Clerk
1 Araria 2 0 1
2 Arwal 1 1 1
3 Aurangabad 1 0 2
4 Banka 2 1 1
5 Begusarai 1 1 1
6 Bhagalpur 1 1 2
7 Bhojpur 0 2 0
and so on...
i tried with rand() and newid() like as below,
select Employee.*, Place.PlaceName As RandomPosting from Employee
inner join Place on Place.PlaceID=Employee.EmpNo order by newid()
But unable to select what is required... that is to assign each Employee a PlaceName(from Place) randomly which is not equal to CurrentPosting and Home(in Employee).
Thanks in advance.
WITH cteCrossJoin AS (
SELECT e.*, p.PlaceName,
ROW_NUMBER() OVER(PARTITION BY e.EmpNo ORDER BY NEWID()) AS RowNum
FROM Employee e
CROSS JOIN Place p
WHERE e.Home <> p.PlaceName
)
SELECT *
FROM cteCrossJoin
WHERE RowNum = 1;
I'm working on the adventureworks example database.
I have a table with employee's, which all have a certain manager. So in the table employee's there is a column ManagerID.
Also in the table employee there's a ContactID, which contains the name of that employee.
I would like to have a list with all the managers and their names. How can I pull this off?
The table looks something like
EmployeeID ContactID ManagerID
---------- --------- ---------
1 21 4
2 24 4
3 32 7
4 34 2
5 35 2
6 42 7
7 44 4
So i'll need a DISTINCT list of the managerID, and then search for each managerID their appropreate ContactID.
So:
manager of employee 1 is Employee 4 with the ContactID 34.
manager of employee 3 is Employee 7 with the ContactID 44.
manager of employee 4 is Employee 2 with the ContactID 24.
Thanks.
You can do it joining the table myTable with itself matching manager_id's with employee_id's
select
t.employeeid as employee_id,
t.manager_id as manager_id,
t2.contact_id as manager_contact_id
from mytable t left outer join mytable t2 on t.managerid = t2.employeeid
SELECT ManagerID, EmployeeID, ConactID
FROM ´yourtable´
GROUP BY ManagerID
There you get the grouped data.
If you want to have Managers listed as well you have to JOIN the data again (self-join)