从Where-Clause的多值列表中选择

时间:2012-09-08 01:44:46

标签: sql ms-access multivalue

我正在尝试选择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

我需要输出目前可以处理的所有项目;即,我需要显示SELECT ProjName FROM Projects INNER JOIN Employees ON EmpOnProj.Value = EmpID WHERE AtWork = true GROUP BY ProjName ,因为在Beta上工作的员工正在工作。

目前我不能说“所有员工必须在工作”只有以下内容:

{{1}}

返回两者,因为它看到一个正确的员工并显示项目。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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'

答案 2 :(得分: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
;

答案 3 :(得分: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();