COUNT或UNION或两者兼而有之?

时间:2014-01-05 15:53:54

标签: sql postgresql count

我试图在一个查询中从我的数据库中获取包含以下参数的结果集:

  • 项目中不活跃的员工? AND
  • 在3个项目中不活跃的员工

第一部分很简单,但第二部分很棘手。我需要将两者结合成一个查询。

以下是我的简化表格:

employee
employeeid | ...

project_employee
projectid | active | ...

"有源"可以是A(表示活动)或R(表示拒绝)。

SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE projectid != ?

编辑:!= = =

的instad

- >这给了我所有不在项目中的员工? 但是我如何使第二部分工作?我认为它必须是SELECT COUNT(DISTINCT...,但我所有的尝试都是失败的。

6 个答案:

答案 0 :(得分:1)

如果我的问题是正确的,那么你最终会想要一些类似于此的东西:

 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 <> ?)
  • 左连接:包括完全没有项目的员工
  • 有数:少于3个项目
  • 让bool_and:排除特定项目中的员工

答案 1 :(得分:0)

如果您的查询确实让所有在项目中都不活跃的员工?对于不在三个或更多项目中活跃的员工,你可以做这样的事情:

SELECT name
FROM employee e INNER JOIN project_employee pe ON e.employeeid = pe.employeeid
GROUP BY e.employeeid
HAVING COUNT(*) >= 3

答案 2 :(得分:0)

实际上,您的查询会为您提供项目中的员工。为了得到那些没有的人,你需要这样的东西:

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

要让处于状态A的3个项目中不活跃的员工,请执行类似的操作。要获得最终答案,请将两个查询合并在一起。

答案 3 :(得分:0)

另一种解决方案是使用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

答案 4 :(得分:0)

这给出了不活跃的员工姓名,即3个项目中的active ='R'

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

但是当你打算使用从第一个条件获得的结果集来进行上述结果集的UNION时,即在项目中没有活动的就业

SELECT name
FROM employee e
INNER JOIN project_employee pe
ON e.employeeid = pe.employeeid
WHERE active='R'

然后上面发布的第一个查询,即在3个项目中处于非活动状态的员工是没有意义的 在3个项目中不活跃的员工也是在特定项目中不活跃的员工,因此您每次都会获得相同的最终结果集。

例如

员工不活跃

xyz
pqr
mno
lmn
abc

员工在3个项目中处于非活动状态

xyz
lmn

申请工会

xyz
pqr
mno
lmn
abc

UNION

xyz
lmn

最终结果集与第一个结果集相同

xyz
pqr
mno
lmn
abc

答案 5 :(得分:0)

我会从一个让员工积极参与3个项目的查询开始 此查询提供在3个或更多项目中处于活动状态的员工:

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'

如果我们希望在3个项目中使用staffess,那么where子句中的这个条件可以帮助:

   AND NOT EXISTS(
      SELECT 1 FROM project_employee pe4
      WHERE pe3.employeeid = pe4.employeeid
        AND pe3.projectid < pe4.projectid
        AND pe4.active = 'A'
   )

现在 - 简单地说 - 将以下条件添加到原始查询中:

 ........
 AND employe_id NOT IN (
    SELECT pe1.employeeid
    .......  
    put the above query here
    .......
    .......
 )

最终查询可能如下所示:

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'
       )    
      */ 
)