SQL joins from same table column - sql

Have two tables
employees: employee_id , employee_name, manager_id, department_id
departments: department_id,manager_id
I need to show employee id, employee name, manager name, and manager id, yet I cannot figure out how to show manager name. Here is what I have even though it is very wrong and doesn't show the real manager name
SELECT e.last_name "Employee", e.employee_id "Emp#", e.last_name "Manager",
d.manager_id "Mgr#"
FROM employees e,
departments d;

Figured it out using keyword Join - Only required use of one table twice
SELECT e.last_name "Employee", e.employee_id "Emp#", e2.last_name "Manager",
e.manager_id "Mgr#"
FROM employees e
JOIN employees e2 ON e2.employee_id = e.manager_id;
Or without Keyword Join / using a simple join
SELECT e.last_name "Employee", e.employee_id "Emp#", e2.last_name "Manager",
e.manager_id "Mgr#"
FROM employees e, employees e2
WHERE e2.employee_id = e.manager_id

you can do inner join on manager_id so only the matching rows remain
SELECT last_name as "Employee", employee_id as "Emp#", last_name as "Manager",
manager_id as "Mgr#"
FROM employees as e1
INNER JOIN departments as d2
ON e1.manager_id = d2.manager_id;

Related

How can I display all records including those with null values in manager_id using conditions?

How can I display all records including those with null values in manager_id using conditions?
select e.last_name as Employee, e.employee_id as Emp#, d.last_name as Manager, d.employee_id as Mngr#
from hr.employees e, hr.employees d
where e.manager_id = d.employee_id
and e.manager_id is null;
What you are looking for is
enter image description here
select e.last_name as Employee, e.employee_id as Emp#, d.last_name as Manager, d.employee_id as Mngr#
from hr.employees e left join hr.employees d
on e.manager_id = d.employee_id;

Display Manager name instead of Manager Id in Oracle ADF

Employees table contains -
Employee_Id,
Manager_Id,
First_Name,
Last_Name
I want to display manager name instead of id
LOV cannot be used
Current Query in VO:
SELECT
Employees.EMPLOYEE_ID,
Employees.FIRST_NAME,
Employees.LAST_NAME,
JobObject.JOB_TITLE,
Employees.COMMISSION_PCT,
Departments.DEPARTMENT_NAME,
Departments.DEPARTMENT_ID,
JobObject.JOB_ID,
(First_Name||' '||Last_Name) AS VIEW_ATTR,
Employees.SALARY,
Employees.MANAGER_ID
FROM EMPLOYEES Employees,
DEPARTMENTS Departments,
JOBS JobObject
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
I assume that you want to show Manager Name along with employee details. Is so then following query will be helpful.
SELECT emp.EMPLOYEE_ID,
emp.FIRST_NAME,
emp.LAST_NAME,
JobObject.JOB_TITLE,
emp.COMMISSION_PCT,
dept.DEPARTMENT_NAME,
dept.DEPARTMENT_ID,
JobObject.JOB_ID,
(emp_manager.First_Name || ' ' || emp_manager.Last_Name) AS manager_name,
emp.SALARY
FROM EMPLOYEES emp
JOIN DEPARTMENTS dept ON (emp.department_id = dept.department_id)
JOIN JOBS JobObject ON (emp.job_id = JobObject.job_id)
JOIN EMPLOYEES emp_manager ON( emp.manager_id = emp_manager.employee_id )
If I understood correctly ,the reason why you get nothing is related to join,when you use commas in the FROM clause may you get problem.
and for managername if you have a manager table you have to inner join with that or try this:
SELECT Employees.EMPLOYEE_ID,
Employees.FIRST_NAME,
Employees.LAST_NAME,
JobObject.JOB_TITLE,
Employees.COMMISSION_PCT,
Departments.DEPARTMENT_NAME,
Departments.DEPARTMENT_ID,
JobObject.JOB_ID,
(Employees.First_Name+' '+Employees.Last_Name) AS ManagerName,
Employees.SALARY,
Employees.MANAGER_ID
FROM EMPLOYEES Employees,
inner join
DEPARTMENTS Departments on Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
left outer join
JOBS JobObject on JobObject.Job_Id=Employees.Job_Id
where Employees.MANAGER_ID is not null and Employees.MANAGER_ID in (EMPLOYEE_ID from employees)

SQL Print departments that have employees

I have two tables departments and employees.
The department table has as primary key department_id. The employees table has as foreign key department_id. I want to print all departments that have employees.
I've tried using a syntax as, but it's not good.
SELECT
departments.department_id, employees.department_id
FROM
departments, employees
WHERE
departments.department_id <> employees.department_id;
"I want to print all departments that have employees"
-- I want to print all departments
SELECT *
FROM departments d
WHERE EXISTS (
-- that have employees
SELECT *
FROM employees e
WHERE e.department_id = d.department_id
);
Simple solution:
select * from departments
where department_id in (select department_id from employees)
You need all the departments referenced in the Employees table.
So you need to go over every employee record whose department_id is not null. Then you have a department that has an employee related.
SELECT
d.department_id,
d.department_name
FROM
departments d
JOIN employees e ON e.department_id = d.department_id
WHERE e.department_id IS NOT NULL
GROUP BY d.department_id
SELECT
DISTINCT d.department_id
FROM
departments d
JOIN employees e ON e.department_id = d.department_id

how Display the names of employees who are not working as managers?

i need to retrieve all employees who are not working as managers
i tried with this code >
SELECT MGR.LAST_NAME ,
E.EMPLOYEE_ID
FROM EMPLOYEES E , (SELECT M.LAST_NAME ,
M.EMPLOYEE_ID
FROM EMPLOYEES E , EMPLOYEES M
WHERE E.MANAGER_ID = M.EMPLOYEE_ID) MGR
WHERE E.EMPLOYEE_ID = MGR.EMPLOYEE_ID
SELECT
E.LAST_NAME,
E.EMPLOYEE_ID
FROM EMPLOYEES E
WHERE EMPLOYEE_ID not in
(SELECT MANAGER_ID FROM EMPLOYEES where MANAGER_ID is not null)

Employees with largest salary in department

I found a couple of SQL tasks on Hacker News today, however I am stuck on solving the second task in Postgres, which I'll describe here:
You have the following, simple table structure:
List the employees who have the biggest salary in their respective departments.
I set up an SQL Fiddle here for you to play with. It should return Terry Robinson, Laura White. Along with their names it should have their salary and department name.
Furthermore, I'd be curious to know of a query which would return Terry Robinsons (maximum salary from the Sales department) and Laura White (maximum salary in the Marketing department) and an empty row for the IT department, with null as the employee; explicitly stating that there are no employees (thus nobody with the highest salary) in that department.
Return one employee with the highest salary per dept.
Use DISTINCT ON for a much simpler and faster query that does all you are asking for:
SELECT DISTINCT ON (d.id)
d.id AS department_id, d.name AS department
,e.id AS employee_id, e.name AS employee, e.salary
FROM departments d
LEFT JOIN employees e ON e.department_id = d.id
ORDER BY d.id, e.salary DESC;
->SQLfiddle (for Postgres).
Also note the LEFT [OUTER] JOIN that keeps departments with no employees in the result.
This picks only one employee per department. If there are multiple sharing the highest salary, you can add more ORDER BY items to pick one in particular. Else, an arbitrary one is picked from peers.
If there are no employees, the department is still listed, with NULL values for employee columns.
You can simply add any columns you need in the SELECT list.
Find a detailed explanation, links and a benchmark for the technique in this related answer:
Select first row in each GROUP BY group?
Aside: It is an anti-pattern to use non-descriptive column names like name or id. Should be employee_id, employee etc.
Return all employees with the highest salary per dept.
Use the window function rank() (like #Scotch already posted, just simpler and faster):
SELECT d.name AS department, e.employee, e.salary
FROM departments d
LEFT JOIN (
SELECT name AS employee, salary, department_id
,rank() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
FROM employees e
) e ON e.department_id = d.department_id AND e.rnk = 1;
Same result as with the above query with your example (which has no ties), just a bit slower.
This is with reference to your fiddle:
SELECT * -- or whatever is your columns list.
FROM employees e JOIN departments d ON e.Department_ID = d.id
WHERE (e.Department_ID, e.Salary) IN (SELECT Department_ID, MAX(Salary)
FROM employees
GROUP BY Department_ID)
EDIT :
As mentioned in a comment below, if you want to see the IT department also, with all NULL for the employee records, you can use the RIGHT JOIN and put the filter condition in the joining clause itself as follows:
SELECT e.name, e.salary, d.name -- or whatever is your columns list.
FROM employees e RIGHT JOIN departments d ON e.Department_ID = d.id
AND (e.Department_ID, e.Salary) IN (SELECT Department_ID, MAX(Salary)
FROM employees
GROUP BY Department_ID)
This is basically what you want. Rank() Over
SELECT ename ,
departments.name
FROM ( SELECT ename ,
dname
FROM ( SELECT employees.name as ename ,
departments.name as dname ,
rank() over (
PARTITION BY employees.department_id
ORDER BY employees.salary DESC
)
FROM Employees
JOIN Departments on employees.department_id = departments.id
) t
WHERE rank = 1
) s
RIGHT JOIN departments on s.dname = departments.name
Good old classic sql:
select e1.name, e1.salary, e1.department_id
from employees e1
where e1.salary=
(select maxsalary=max(e.salary) --, e. department_id
from employees e
where e.department_id = e1.department_id
group by e.department_id
)
Table1 is emp - empno, ename, sal, deptno
Table2 is dept - deptno, dname.
Query could be (includes ties & runs on 11.2g):
select e1.empno, e1.ename, e1.sal, e1.deptno as department
from emp e1
where e1.sal in
(SELECT max(sal) from emp e, dept d where e.deptno = d.deptno group by d.dname)
order by e1.deptno asc;
SELECT
e.first_name, d.department_name, e.salary
FROM
employees e
JOIN
departments d
ON
(e.department_id = d.department_id)
WHERE
e.first_name
IN
(SELECT TOP 2
first_name
FROM
employees
WHERE
department_id = d.department_id);
`select d.Name, e.Name, e.Salary from Employees e, Departments d,
(select DepartmentId as DeptId, max(Salary) as Salary
from Employees e
group by DepartmentId) m
where m.Salary = e.Salary
and m.DeptId = e.DepartmentId
and e.DepartmentId = d.DepartmentId`
The max salary of each department is computed in inner query using GROUP BY. And then select employees who satisfy those constraints.
Assuming Postgres
Return highest salary with employee details, assuming table name emp having employees department with dept_id
select e1.* from emp e1 inner join (select max(sal) avg_sal,dept_id from emp group by dept_id) as e2 on e1.dept_id=e2.dept_id and e1.sal=e2.avg_sal
Returns one or more people for each department with the highest salary:
SELECT result.Name Department, Employee2.Name Employee, result.salary Salary
FROM ( SELECT dept.name, dept.department_id, max(Employee1.salary) salary
FROM Departments dept
JOIN Employees Employee1 ON Employee1.department_id = dept.department_id
GROUP BY dept.name, dept.department_id ) result
JOIN Employees Employee2 ON Employee2.department_id = result.department_id
WHERE Employee2.salary = result.salary
SQL query:
select d.name,e.name,e.salary
from employees e, depts d
where e.dept_id = d.id
and (d.id,e.salary) in
(select dept_id,max(salary) from employees group by dept_id);
Take look at this solution
SELECT
MAX(E.SALARY),
E.NAME,
D.NAME as Department
FROM employees E
INNER JOIN DEPARTMENTS D ON D.ID = E.DEPARTMENT_ID
GROUP BY D.NAME