2014-01-05 107 views
0

我試圖讓與我的DB以下參數一個結果在一個查詢:COUNT或UNION還是兩者?

  • 員工不在項目的活躍? 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...,但我所有的嘗試都失敗了。

+0

實際上,即使您進行了編輯,您可能也會從該項目中獲得員工。如果你的參數是2,Joe在項目1和2中,你的查詢將返回他。 –

回答

0

如果您的查詢的確能夠獲得所有在項目中不活躍的員工?比你能在三個或更多的項目不活躍的員工做這樣的事情:

SELECT name 
FROM employee e INNER JOIN project_employee pe ON e.employeeid = pe.employeeid 
GROUP BY e.employeeid 
HAVING COUNT(*) >= 3 
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 

讓員工誰是不是在3個項目狀況的活躍,做類似的事情。爲了得到最終答案,將兩個查詢結合在一起。

+0

啊我應該使用projectid!=?。這不會工作嗎? – cflx

+0

不一定。詳情請參閱我對您問題的評論。 –

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 
+0

這是一種非常直觀和簡單的方法。不幸的是,不會變得緩慢。 –

0

這給那些不活動,即激活= 3個項目

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「R」的員工姓名以上結果集,結果集從第一個條件獲得即employess未在項目中活躍

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 
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 <> ?) 
  • LEFT JOIN:包括沒有項目員工全部
  • 計數:少於3個項目
  • 有bool_and:排除特定項目中的員工
+0

(它可能需要'coalesce(...,true)'在'bool_and'中以確保對於沒有分配給任何項目的用戶來說是成立的。) –

0

我會從一個查詢中爲員工激活3個項目開始。
這個查詢給出employess,在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' 

如果我們想employess acive恰好3個項目,那麼在這種情況下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' 
     )  
     */ 
) 
相關問題