2012-09-08 46 views
2

我試圖選擇所有Projects,其中有Employees誰是AtWork從以下條款中選擇多個值條目

Projects: 
ProjName | EmpOnProj 
-------------------------- 
Alpha  | 1, 2, 3 
Beta  | 1, 3 

Employees: 
EmpID  | EmpName | AtWork 
------------------------------------- 
1   | John  | TRUE 
2   | Mark  | FALSE 
3   | Mary  | TRUE 

我需要輸出可能現在要工作的所有項目;即我需要顯示Beta,因爲使用Beta的員工正在工作。

目前我不能說「所有員工必須在工作中」只有以下:

SELECT ProjName FROM Projects INNER JOIN 
Employees ON EmpOnProj.Value = EmpID 
WHERE AtWork = true 
GROUP BY ProjName 

返回兩個,因爲它看到了一個正確的員工,並顯示該項目。

+0

你的表似乎表明了項目表比你的SQL提供什麼不同的結構。 EmpOnProj值是否在單獨的行上,或者您的表是否需要標準化? –

+0

不知道Access是如何實現的,但由於這只是一個快速的家庭使用系統(員工的事情是一種簡化),我使用了組合框的多值選項。不知何故,「EmpOnProj.Value = EmpID」的作品,這意味着它似乎像你想要的那樣搜索CSV。 – StuckAtWork

回答

3

我想我解決了這個問題。基本上我說,「秀除了那些所有的項目,其中有人是不上班」

http://sqlfiddle.com/#!3/36c48/2

SELECT DISTINCT 
    p_global.ProjName 

FROM 
    Projects AS p_global 

WHERE 
    p_global.ProjName NOT IN 
    (SELECT DISTINCT 
     p1.ProjName 

    FROM 
     Projects p1 INNER JOIN Employees AS e ON p1.EmpOnProj = e.EmpID 

    WHERE 
     e.AtWork = 0) 

有可能是一個簡單的解決方案,但這個工作(或它看起來像它反正):)

修改:刪除GROUP BY s,如評論建議。

+1

哦,正如弗雷德指出的那樣,你的問題很難回答,因爲你的表格沒有正常化。 – ApplePie

+0

但我的解決方案並不假設標準化的表格,它現在可以和您的表格佈局一起工作。 – ApplePie

+1

看起來不錯,可以不必組簡化,但只是做一個明顯的: SELECT DISTINCT p_global.ProjName FROM 項目,p_global WHERE p_global.ProjName NOT IN (SELECT p1.ProjName FROM Projects p1 INNER JOIN Employees AS e ON p1.EmpOnProj = e.EmpID WHERE e.AtWork = 0) – Turnkey

1

如果不能真正回答你的問題,但這個東西可以引導你通過簡化,並可以幫助你解決你的問題。目前您的表格格式不正確。而不是用逗號分隔值,爲什麼不用行來代替呢?像這樣,

Projects: 
ProjName | EmpOnProj 
-------------------------- 
Alpha  | 1 
Alpha  | 2 
Alpha  | 3 
Beta  | 1 
Beta  | 3 

通過這種方式,您可以輕鬆地連接兩個表。例如

SELECT a.EmpID, a.EmpName, 
     iif (ISNULL(b.EmpOnProj), 'False', 'True') AtWork 
FROM Employees a 
     LEFT JOIN Projects b 
      ON a.EmpID = b.EmpOnProj 
WHERE b.ProjName = 'Beta' 
0

假設你超越EmpOnProj列,其中,因爲在你的例子實施,違反first normal form,並與所謂ProjEmp關聯實體,其主要關鍵是更換(ProjName,的EmpID)

SELECT p.ProjName FROM Projects p 
LEFT OUTER JOIN 
(SELECT eop.ProjName FROM ProjEmp eop 
    INNER JOIN JOIN Employees e 
    ON e.EmpId = eop.EmpId 
    AND e.AtWork = FALSE 
) AS empNotHere 
ON empNotHere.ProjName = p.ProjName 
WHERE empNotHere.ProjName IS NULL 
; 
+0

沒有保證,如果這將實際上在MS Access工作,但它是關於香草儘可能。 –

0

我假設我誤解了你的問題,因爲你的SQL似乎與你提供的模式相矛盾。但是,如果你的桌子按照你列出的方式進行了格式化,你必須跳過籃球。這是一個涉及製作UDF的解決方案,以避免極其複雜的SQL。

一下添加到模塊:

Function WhoIsAtWork() As String 
    Dim rs As Recordset 
    Set rs = CurrentDb.OpenRecordset("Select * from Employees where AtWork = true Order by EmpID") 
    Do While Not rs.EOF 
     WhoIsAtWork = WhoIsAtWork & rs!EmpID & ", " 
     rs.MoveNext 
    Loop 
    If Len(WhoIsAtWork) <> 0 Then 
     WhoIsAtWork = Left(WhoIsAtWork, Len(WhoIsAtWork) - 2) 
    End If 
    rs.Close 
    Set rs = Nothing 
End Function 

那麼你的SQL是這樣的:

SELECT ProjName 
FROM Projects 
WHERE Projects.EmpOnProj=WhoIsAtWork();