Query to get employee of different departments - sql

I have 3 tables: Employee, Department and employeeProject.
The relation between employee and employeeproject is one-to-many. The relation between employee and department is many-to-one.
I want to write a query to select 10 employees who have worked in projects 3 and 4. The query should return employees of different departments if possible.
The query below kind of works. The only problem is that the relationship between employee and employeeproject is one-to-many, so it might return the same employee number multiple times.
I cannot use distinct because all fields in the order by clause should be used in select when using distinct.
select top 10 empid from employee e
inner join department d on d.depId=e.depid
inner join employeeProject p on p.empid=e.empid
where p.projectID in (3,4)
order by row_number() over(partition by e.depId order by e.empid)

Bit of a guess, but use an EXISTS?
SELECT TOP 10 e.empid
FROM employee e
JOIN department d ON e.depid = d.depid
WHERE EXISTS (SELECT 1
FROM employeeproject p
WHERE p.emdid = e.empid
AND p.projectid IN (3,4))
ORDER BY e.depid, e.empid;

I suggest aggregating by employee, and then using an assertion the HAVING clause:
SELECT TOP 10 e.empid
FROM employee e
INNER JOIN department d
ON d.depId = e.depid
INNER JOIN employeeProject p
ON p.empid = e.empid
WHERE
p.projectID IN (3,4)
GROUP BY
e.empid
HAVING
MIN(p.projectID) <> MAX(p.projectID);
If the minimum and maximum projectID are not equal for a given employee, after restricting to only projects 3 and 4, then it implies that this employee meets the criteria.

Why not just use select distinct?
select distinct top 10 empid
from employee e inner join
employeeProject p
on p.empid = e.empid
where p.projectID in (3, 4)
order by row_number() over (partition by e.depId order by e.empid);
Note that the department table is not needed.
Alternatively,
select top (10) e.*
from employee e
where exists (select 1
from employeeprojects ep
where p.emdid = e.empid and
p.projectid in (3, 4)
)
order by row_number() over (partition by e.depid order by newid());

Related

I need to get number of employees per depatment

This gets me the number of employees per department
SELECT department, COUNT(idEmployees) empCount
FROM employees
GROUP BY department;
You could join on departments to get the buildingID, and then group by that:
SELECT buildingID, COUNT(*)
FROM employees e
JOIN department d ON e.department = d.departmentID
GROUP BY buildingID
i think this is the solution
select d.buildingID, count(e.ID)
from department d
inner join employees e
on d.departmentID = e.department
group by d.buildingID
This question can be answered in two ways. Firstly, if all employees of a department must be attached in a building. Secondly few employees of a department are attached to a building.
For one where employees are attached to a building it's mandatory
SELECT d.buildingId
, COUNT(e.id) count_employee
FROM departments d
INNER JOIN employees e
ON d.departmentid = e.department
GROUP BY d.buildingId
For second where employees are attached to a building but it's optional. In that case LEFT JOIN is used.
SELECT b.buildingId
, COALESCE(t.count_employee, 0) count_employee
FROM building b
LEFT JOIN (SELECT d.buildingId
, COUNT(e.id) count_employee
FROM departments d
INNER JOIN employees e
ON d.departmentid = e.department
GROUP BY d.buildingId) t
ON b.buildingId = t.buildingId
If a building is attached with multiple departments and one employee is assigned with multiple departments then count building wise same employee is only onetime not multiple times. In that case DISTINCT keyword is used inside COUNT().
SELECT d.buildingId
, COUNT(DISTINCT e.id) count_employee
FROM departments d
INNER JOIN employees e
ON d.departmentid = e.department
GROUP BY d.buildingId

How to show the employess who have only one project, and also their project. Many to Many relationship problem

Project Table:
Employee Table
Connector Table:
Therea are 6 employees who have only one project
one of the prjects is P2, it has 5 employees
and the other project is P3 which has 1 employee
Select * from Emp
Select * from Project
Select * from PrEmpConnector
------------------------------------------------
Select t.EmpId as Employee_Id, t.Project_Name
from (
Select
PE.EmpId,
P.Project_Name
from PrEmpConnector as PE
inner join Project as P on P.Id in(
Select sum(t.ProjectId)
from PrEmpConnector as t
group by t.EmpId
having COUNT(t.EmpId) = 1
)
) as t
group by t.Project_Name, t.EmpId
having t.EmpId in (
Select t.EmpId
from PrEmpConnector as t
group by t.EmpId
having COUNT(*) = 1
)
select emp.name,emp.surname,project.project_name from
PrEmpConnector
inner join emp on emp.id=PrEmpConnector.emp_id
inner join Project on Project.id=PrEmpConnector.projectid
where emp.empid in (
select emp_id from PrEmpConnector
group by emp_id having count(projectid) =1)
If you are looking for employees that only work on one project, you can join the three tables, aggregate by employee, and filter on groups that contain only one record with a having clause:
select
e.id employee_id,
e.name employee_name,
min(p.id) project_id,
min(p.project_name) project_name
from project p
inner join connector c on c.projectId = p.id
inner join employee e on e.id = c.employeeId
group by e.id, e.name
having count(*) = 1

How to get all departments with Employee number

I have an EmployeeDepartmetn juction table like this. I have all the departments in Depeartment table and employees in Employee table..
I want to get departments for an particular employee along with the all the departments available in depeartment table.
It should be like Select DepartmentId, DepartmentName, EmployeeID from Query.
Main criteria here is, Need to display NULL if the employee dont have that department. I am confused here...please help.
Please give Linq Query
Thanks in Advance
Put criteria in your left join:
Select distinct a.DeptID, b.DepartmentName, b.EmployeeID
From Department a
left join EmployeeDepartment b
on a.DeptID = b.DeptID and b.EmployeeID = 1 --insert employee ID here
It will show all departments (even those with no employees), then show the employee ID you chose in the third column only if that employee is assigned there.
You can do this with conditional aggregation:
select DeptId,
max(case when EmployeeId = 1 then EmployeeId end) as EmployeeId
from EmployeeDepartment ed
group by DeptId;
EDIT:
If you have a departments table as well:
select d.deptid, d.name, ed.employeeid
from Departments d left join
EmployeeDepartment ed
on d.deptid = ed.deptid and
ed.employeeid = 1;

Isa relationship query in sql

I have a disjoint relationship among my tables: Employee(empId PK, name), HourlyEmployee(empId PK FK, hourlySalary) empId is a reference to Employee.empId,
MonthlyEmployee(empId Pk FK, monthlySalary) empId is a reference to Employee.empId.
How can I create a query resulting AllEmployees(empId,name,hourlySalary,monthlySalary).
For all hourly employees monthlySalary will be null and for all monthly employess hourly salary will be null
Regards,
Tural
Use outer joins to get all employees no matter if they exist in HourlyEmployee or MonthlyEmployee (or neither of them).
select e.empid, e.name, h.hourlysalary, m.monthlysalary
from employee e
left outer join hourlyemployee h on h.empid = e.empid
left outer join monthlyemployee m on m.empid = e.empid;
select e.empid, e.name, h.hourlysalary, m.monthlysalary
from employee e
left outer join hourlyemployee h on h.empid = e.empid
left outer join monthlyemployee m on m.empid = e.empid
where (h.hourlysalary is null) or (m.monthlysalary is null);

I need sql query to merge info from 2 tables

i`m new in SQL and i need a tip. I got 2 tables ( employee and department ),
employee table as E:
id (int), name(nvarchar), gender(nvarchar), departmentID(int), dateofbirth(datetime)
department table as D :
dep_id(int), name(nvarchar), location(nvarchar), boss_id(int)
That`s what i need as output table:
E.id / E.name / D.name / D.location / (and last which i cant get with simple join is:) D.boss.name (not simple boss id but real employee name from E table)
Just simple question for advanced people :-)
Join the table a second time for the boss. (This is assuming that boss_id FK's to Employee)
SELECT
E.Id,
E.Name,
D.Name,
D.Location,
B.Name
FROM Employee E
INNER JOIN Department D on E.DepartmentID = D.Dep_id
INNER JOIN Employee B ON D.Boss_id = B.Id
You can write a query using cte as well:
WITH CTE AS(
Select
e.ID,
e.name,
d.boss_id,
d.Location as DepartmentLocation,
d.name as DepartmentName
From Employee e
INNER JOIN Department d on d.boss_id =E.id
)
Select c.id, c.name, e.name as BossName, c.DepartmentLocation, c.DepartmentName
from cte c
Inner Join Employee e1 on e1.id=c.boss_id
SELECT e.Id, e.Name, d.Name, d.Location,
(
SELECT e2.Name
FROM tblEmployee as e2
WHERE e2.id = d.boss_id
) AS [Boss name]
FROM tblEmployee as e
INNER JOIN tblDepartment as d
ON e.DepartmentID = d.dep_ID