Employee Table and Manager Table - sql

I have Employee Table
EMPID | EMPNAME
1 | A
2 | B
I have [Manager Table]
MNGID | EMPID
2 | 1
The above MNGID Refers TO Employee Table Means B is the Manager of A.
I wanted query to display Manager Name and Employee Name. Please Sugget Result

This should do the job for you:
select E.EmpName as EmployeeName, EM.EmpName as ManagerName
FROM Employee E
join Manager M on E.EMPID = M.EMPID
join Employee EM on M.MngID = EM.EMPId

try this[Updated query]:
SELECT
m1.empname as manager,
e.empname as employee
FROM
Manager m
JOIN
Employee e
ON
m.empid = e.empid
JOIN
Employee m1
ON
m1.empid = m.mngid
================
http://www.sqlfiddle.com/#!9/61560b/1

Related

SQL Query: Customer Table Contains Different type of EmpIDs and i want to get their name in a single row

I got a customer table and each customer has 4 different employeeID (tranieeID,RepresenterID,CoridatorID and ManagerID) I want to get all these employees name rather then their ID in single row.
CustomerTable
|CustomerID|CustomerName|tranieeID|RepresenterID |CoridatorID |ManagerID
------------------------------------------------------------------------
01 Mr T 100 101 102 103
EmployeeTable
EmpID | EmpName
---------------
100 Mr A
101 Mr B
102 Mr C
103 Mr D
What I need
CustomerID | CustomerName | tranieeName | RepresenterName | CoridatorName | ManagerName
----------------------------------------------------------------------------------------
01 Mr T Mr A Mr B Mr C Mr D
I did inner join but I got 4 Rows, is there any way to get all these with a single row?
Thank you for your help!
JOIN should work. I would recommend LEFT JOIN in case any of the values are not filled in:
select c.*,
et.empname as traineeName,
er.empname as RepresenterName,
ec.empname as CoridatorIDName,
em.empname as ManagerName
from customertable c left join
employeetable et
on c.traineeID = et.empid left join
employeetable er
on c.RepresenterID = et.empid left join
employeetable ec
on c.CoridatorID = ec.empid left join
employeetable em
on c.ManagerID = em.empid
You could use a correlated subquery in each instance, such as
select c.CustomerId, CustomerName,
(select Empname from EmployeeTable e where e.EmpID=c.TranieeId) TraineeName,
(select Empname from EmployeeTable e where e.EmpID=c.RepresenterId) RepresenterName,
... etc
from CustomerTable c

I want to get data from 3 tables

I have 3 tables employee, jobs and department as below,
------------------- ---------------- ------------------
| employee | | jobs | | department |
------------------- ---------------- ------------------
| empId | | jobId | | deptId |
| fname | | jobTitle | | deptName |
| lname | | | | managerId |
| jobId | | | | |
| managerId | | | | |
| departmentId | | | | |
------------------- ---------------- -------------------
I want to select all data from employee, the job title through jobId, the deptName through deptId and manager name through managerId and employeeId
SELECT EMPLOYEES.EMPLOYEE_ID, EMPLOYEES.FIRST_NAME, EMPLOYEES.LAST_NAME,
EMPLOYEES.JOB_ID, JOBS.JOB_TITLE AS JOB_TITLE, EMPLOYEES.SALARY,
DEPARTMENTS.DEPARTMENT_ID, DEPARTMENTS.DEPARTMENT_NAME AS DEPARTMENT_NAME
FROM EMPLOYEES
LEFT JOIN JOBS ON EMPLOYEES.JOB_ID = JOBS.JOB_ID
LEFT JOIN DEPARTMENTS ON EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
what should I do to get the name of the manager using the empId?
or is there any other way to simplify this block of code?
Just Add another LEFT JOIN to the EMPLOYEES table, but give it an alias, say MANAGERS.
SELECT
EMPLOYEES.EMPLOYEE_ID,
EMPLOYEES.FIRST_NAME,
EMPLOYEES.LAST_NAME,
EMPLOYEES.JOB_ID,
JOBS.JOB_TITLE AS JOB_TITLE,
EMPLOYEES.SALARY,
DEPARTMENTS.DEPARTMENT_ID,
DEPARTMENTS.DEPARTMENT_NAME AS DEPARTMENT_NAME,
MANAGERS.FIRST_NAME AS MANAGER_FIRST_NAME,
MANAGERS.LAST_NAME AS MANAGER_LAST_NAME
FROM EMPLOYEES
LEFT JOIN EMPLOYEES MANAGERS
ON EMPLOYEES.MANAGER_ID = MANAGERS.EMPLOYEE_ID
LEFT JOIN JOBS
ON EMPLOYEES.JOB_ID = JOBS.JOB_ID
LEFT JOIN DEPARTMENTS
ON EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
You can use another left join on employee table to get the manager name.
SELECT (
EMPLOYEES.EMPLOYEE_ID,
EMPLOYEES.FIRST_NAME,
EMPLOYEES.LAST_NAME,
EMPLOYEES.JOB_ID,
JOBS.JOB_TITLE AS JOB_TITLE,
EMPLOYEES.SALARY,
DEPARTMENTS.DEPARTMENT_ID,
DEPARTMENTS.DEPARTMENT_NAME AS DEPARTMENT_NAME,
(MGR.FIRST_NAME + ' ' + MGR.LAST_NAME) AS MANAGER_NAME)
FROM EMPLOYEES
LEFT JOIN JOBS
ON EMPLOYEES.JOB_ID = JOBS.JOB_ID
LEFT JOIN DEPARTMENTS
ON EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID
LEFT JOIN EMPLOYEES MGR
ON EMPLOYEES.MANAGERID = MGR.EMPLOYEE_ID
try using aliases and join back to employee on the manager id.
SELECT
E.EMPLOYEE_ID, E.FIRST_NAME, E.LAST_NAME,
E.JOB_ID, J.JOB_TITLE AS JOB_TITLE, E.SALARY,
D.DEPARTMENT_ID, D.DEPARTMENT_NAME AS DEPARTMENT_NAME,
M.EMPLOYEE_ID as mgr_id, M.FIRST_NAME as mgr_name, M.LAST_NAME as mgr_lname
FROM EMPLOYEES E LEFT JOIN JOBS J ON
E.JOB_ID = J.JOB_ID
LEFT JOIN DEPARTMENTS D ON
E.DEPARTMENT_ID = D.DEPARTMENT_ID
join employees M ON
E.manager_ID = M.employee_ID
The reason this query works is because I am doing a self join back to the Employees table from the main result set that you already established. To put it simply, imagine you made an exact copy of the employees table and called it M. If you took your original query and joined to the M table using the original query's Employee.manager_id to the employee_ID in the M table, then you would have the manager for the employee.
There is no need to create an exact copy of the employee table just to look up the manager. We can just reference the employee table a second time and use an alias (I used M for manager). Then we join from your list of employees using the manager_id to get the employee's manager.
You could do this again to get the manager's manager if you need to. Here is that query:
SELECT
E.EMPLOYEE_ID, E.FIRST_NAME, E.LAST_NAME,
E.JOB_ID, J.JOB_TITLE AS JOB_TITLE, E.SALARY,
D.DEPARTMENT_ID, D.DEPARTMENT_NAME AS DEPARTMENT_NAME,
M.EMPLOYEE_ID as mgr_id, M.FIRST_NAME as mgr_name, M.LAST_NAME as mgr_lname
FROM EMPLOYEES E LEFT JOIN JOBS J ON
E.JOB_ID = J.JOB_ID
LEFT JOIN DEPARTMENTS D ON
E.DEPARTMENT_ID = D.DEPARTMENT_ID
join employees M ON /* The employee's manager */
E.manager_ID = M.employee_ID
LEFT join employees MM ON /* The employee's manager's manager */
M.manager_ID = MM.employee_ID
I used a left join for this last one, because at some point you will get to the top of the management hierarchy and might find that there are no more managers. You could also put a left join on the join employees M
Here it is in Tabular form
Employee_id | Name | manager_id
1 | Fred | 10
2 | Jane | 10
10 | Bob | 20
20 | Betty | Null
Looking at employee # 1. The values of E.employee_id = 1, E.Name = Fred and E.manager_id = 10.
So the relevant lines of the query evaluate as follows:
...
join employees M ON /* The employee's manager */
E.manager_ID /* i.e. 10 */ = M.employee_ID
...
So the M alias now refers to the employee record where M.employee_ID = 10 and as such, M.Name = Bob and M.employee_id = 20.
Using the last version of the query, we could then work out that Fred's manager's manager (i.e. Fred's manager is Bob and Bob's manager is Betty) will have an employee_id of 20 (i.e. M.manager_ID = 20), so the MM.employee_id would be 20 and hence refer to Betty who doesn't seem to have a manager.

SQL Server - Self Join

I have a table as follows
EmployeeID Name ManagerID
2 David 3
3 Roger NULL
4 Marry 2
5 Joseph 2
7 Ben 2
Here Roger is Top Manager
Mike & David are Managers
And rest all are employees
I am looking for output like this:
EmployeeName ManagerName TopManager
Marry David Roger
Joseph David Roger
Ben David Roger
NULL David Roger
I tried using Self Join like:
SELECT e1.Name EmployeeName, ISNULL(e2.name, 'Top Manager') AS ManagerName
FROM Employee e1
LEFT JOIN Employee e2
ON e1.ManagerID = e2.EmployeeID
but it is not giving the output I am looking for.
If you can have different top managers, then a recursive CTE is needed:
with cte as (
select employeeid, name, name as topmanager
from Employee
where managerid is null
union all
select t.employeeid, t.name, cte.topmanager
from Employee t join
cte
on t.managerid = cte.employeeid
)
select *
from cte;
If there is only one top manager, then:
select e.*, topm.name as topmanager
from employee e cross join
(select e2.* from employee e2 where e2.managerid is null) as topm
I think you have to do self join twice to get the desired output.
I created the query in this way and got the output which you have mentioned. Please note that I did not include the last row which has null value, and rest the same as it is.
Query:
create table Employees (EmployeeID int, Name varchar(10), ManagerID int)
Insert into Employees values
(2, 'David' , 3 )
,(3, 'Roger' , NULL)
,(4, 'Marry' , 2 )
,(5, 'Joseph' , 2 )
,(7, 'Ben' , 2 )
select e.name as EmployeeName, e1.name ManagerName, e2.Name TopManager
from Employees e
left join Employees e1 on e.ManagerID = e1.employeeid
left join Employees e2 on e1.ManagerID = e2.EmployeeID
where e.ManagerID is not null and e1.ManagerID is not null
Where condition was given to restrict the manager names in Employee column.
Output:
EmployeeName ManagerName TopManager
Marry David Roger
Joseph David Roger
Ben David Roger

SQL want Repeated result NULL from one table

hi i have problem in sql query example
Employee
empid empname
1 gan
2 sam
Designation
id desig empid
1 sr officerr 1
2 jr officer 1
3 manager 2
i want join tables and want Employee Table repeated records Null
result like
empid name desig id
1 gan sr officerr 1
1 NULL jr officer 2
2 sam manager 3
i working on query but i not getting result
SELECT DISTINCT designatin.empid, employee.empname,designatin.desig
FROM designatin INNER JOIN employee e ON employee.empid = designatin.empid
GROUP BY employee.empid, employee.empname, designatin.desig
can anybody have solution?
Change the inner join to a left join:
SELECT DISTINCT designatin.empid, employee.empname,designatin.desig
FROM designatin LEFT JOIN employee e ON employee.empid = designatin.empid
GROUP BY employee.empid, employee.empname, designatin.desig
Let try this, it will help you
SELECT e.empid, e.empname,d.desig ,d.id
FROM employee e
INNER JOIN Designation d ON e.empid = d.empid
See DEMO

Select records that appear more than once

I am trying to select records that appear more than once and are part of a specific department plus other departments.
So far the query that I have is this:
SELECT employeeCode, employeeName
FROM
Employees
WHERE
Department <> 'Technology'
AND employeeCode IN (SELECT employeeCode
FROM Employees
GROUP BY employeeCode HAVING COUNT(*) > 1)
The problem is that I want to select employees which are part of the Technology department, but they also participate in other departments.
So, they must be from the Technology department, but they could also be from the Household department. In the database it could look like:
1 | A1 | Alex | Technology
2 | A2 | Thor | Household
3 | A3 | John | Cars
4 | A3 | John | Technology
5 | A4 | Kim | Technology
6 | A4 | Kim | Video Games
So basically the query should return:
A3 | John |
A4 | Kim |
I think it's a small part that I am missing but..
Any ideas on how to filter/sort it so that it always uses the technology and the other departments?
Btw, I tried searching but I couldn't find a problem like mine..
If you want employees that could be in the technology department and another department:
select e.employeeCode, e.employeeName
from employees e
group by e.employeeCode, e.employeeName
having sum(case when e.department = 'Technology' then 1 else 0 end) > 0 and
count(*) > 1;
This assumes no duplicates in the table. If it can have duplicates, then use count(distinct department) > 1 rather than count(*) > 1.
Try this:
SELECT E.employeeCode, E.employeeName
FROM Employees E
INNER JOIN (SELECT DISTINCT E1.employeeCode, E1.employeeName
FROM Employees E
WHERE E.Department = 'Technology'
) AS A ON E.employeeCode = A.employeeCode AND E.employeeName = A.employeeName
GROUP BY E.employeeCode, E.employeeName
HAVING COUNT(*) > 1;
You can use EXISTS with correlated sub-query joining on the same table with different condition.
SELECT e1.employeeCode, e1.employeeName
FROM Employees e1
WHERE e1.Department = 'Technology'
AND EXISTS (SELECT * FROM Employees e2
WHERE e1.employeeCode = e2.employeeCode
AND e2.Department <> 'Technology')
This will work for your case:
SELECT a.employeeCode, a.employeeName
FROM Employees a, Employees b
WHERE
a.Department = 'Technology'
AND
b.Department <> 'Technology'
AND
a.employeeCode = b.employeeCode
AND
a.employeeID <> b.employeeID