I'm trying to get a resultset with the following parameters from my DB in one query:
The first part is easy but the second part is tricky. And I need to combine the both into one query.
Here are my simplified tables:
employeeid | ... projectid | active | ...
"active" can be A (for active) or R (for refused).
SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE projectid != ?
EDIT: != instad of =
-> That gives me all the employees that are not in project ? But how can I make the second part work? I figured it had to be something with SELECT COUNT(DISTINCT...
but all my tries have been failures.
If I get the question right, you'll want something that resembles this in the end:
select employees.employee_id
from employees
left join projects
on projects.employee_id = employees.employee_id
and projects.active = 'A'
group by employees.employee_id
having count(*) < 3
and bool_and(projects.project_id <> ?)
If your query does indeed get all employees that are not active in project ? than you could do something like this for the employees not active in three or more projects:
SELECT name
FROM employee e INNER JOIN project_employee pe ON e.employeeid = pe.employeeid
GROUP BY e.employeeid
HAVING COUNT(*) >= 3
Actually, your query gives you employees who are in a project. To get those who are not, you need something like this:
select name
from employee e join
(select employee_id
from employee
except
select employee_id
project_employee
where projected = ?) temp on temp.employee_id = employee.employee_id
To get employees who are not active in 3 projects with status A, do something similar. To get the final answer, union the two queries together.
Another solution is to use NOT IN
SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE projectid NOT IN (1, 5, 9)-- ids of the 3 projects, you've talked about
This gives names of employees that are not active ie active='R' in 3 projects
SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE active='R'
GROUP BY name
HAVING COUNT(projectid)=3
But when you are going to do UNION of above resultset with resultset obtained from first condition ie employess not active in project
SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE active='R'
then the first query posted above ie employees inactive in 3 projects is pointless because employees not active in exactly 3 projects are also employees not active in a particular project and thus you would get same final resultset everytime.
eg
Employees inactive
xyz
pqr
mno
lmn
abc
Employees inactive in 3 projects
xyz
lmn
Applying union
xyz
pqr
mno
lmn
abc
UNION
xyz
lmn
Final Resultset which is same as 1st resultset
xyz
pqr
mno
lmn
abc
I would start from a query that gives employees active in 3 projects.
This query gives employess that are active in 3 or more projects:
SELECT DISTINCT pe1.employeeid
FROM project_employee pe1
JOIN project_employee pe2
ON pe1.employeeid = pe2.employeeid
AND pe1.projectid < pe2.projectid
JOIN project_employee pe3
ON pe2.employeeid = pe3.employeeid
AND pe2.projectid < pe3.projectid
WHERE pe1.active = 'A'
AND pe2.active = 'A'
AND pe3.active = 'A'
If we want employess acive in exactly 3 projects, then this condition in the where clause can help:
AND NOT EXISTS(
SELECT 1 FROM project_employee pe4
WHERE pe3.employeeid = pe4.employeeid
AND pe3.projectid < pe4.projectid
AND pe4.active = 'A'
)
And now - simply - add the below condition to the original query:
........
AND employe_id NOT IN (
SELECT pe1.employeeid
.......
put the above query here
.......
.......
)
The final query may look like:
SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE projectid != ?
AND e.employeeid NOT IN (
SELECT pe1.employeeid
FROM project_employee pe1
JOIN project_employee pe2
ON pe1.employeeid = pe2.employeeid
AND pe1.projectid < pe2.projectid
JOIN project_employee pe3
ON pe2.employeeid = pe3.employeeid
AND pe2.projectid < pe3.projectid
WHERE pe1.active = 'A'
AND pe2.active = 'A'
AND pe3.active = 'A'
/* --- uncomment when exactly 3 projects are required
AND NOT EXISTS(
SELECT 1 FROM project_employee pe4
WHERE pe3.employeeid = pe4.employeeid
AND pe3.projectid < pe4.projectid
AND pe4.active = 'A'
)
*/
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.