2

誰が誰であるかをすべて選択しようとしProjectsEmployeesいます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

1 人の正しい従業員が表示され、プロジェクトが表示されるため、両方が返されます。

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

あなたのSQLはあなたが提供したスキーマと矛盾しているように見えるので、私はあなたの質問を誤解していると思います. しかし、あなたのテーブルがあなたがリストしたようにフォーマットされている場合は、フープを飛び越える必要があります. 非常に複雑な SQL を回避するために、UDF を作成することを含むソリューションを次に示します。

これをモジュールに追加します。

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 に答える
0

あなたの例で実装されているように、最初の正規形に違反する EmpOnProj 列を超えて移動し、主キーが (ProjName, EmpID) である ProjEmp と呼ばれる連想エンティティに置き換えるとします。

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 に答える