2012-09-08 43 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();