2

我正在尝试选择所有Projects拥有Employeeswho are 的人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

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

4

4 回答 4

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。

于 2012-09-08T02:23:00.007 回答
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'
于 2012-09-08T01:55:20.880 回答
0

假设您超出了 EmpOnProj 列,如您的示例中所实现的,该列违反了第一范式,并将其替换为名为 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
;
于 2012-09-08T02:11:31.937 回答
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();
于 2012-09-08T02:56:09.333 回答