4

私はSQLクエリで立ち往生しています。従業員、タスク テーブル、およびそれらの間の多対多の関連付けがあるとします。テーブルは次のようになります。

employees
id|name
1 | John
2 | Peter
3 | Mike

tasks
id | name
1 | Support
2 | Programming
3 | Call customers
4 | Write Newsletters
5 | Write Invoices

employees_tasks
employee_id | task_id
1 | 1
1 | 2
2 | 3
2 | 4
2 | 5
3 | 2

ここで、「プログラミング」をタスクとしているすべての従業員を取得したいと考えています。正しいクエリは次のとおりです。

SELECT employees.id, employees.name
FROM employees 
    INNER JOIN employees_tasks ON employees.id = employees_tasks.employee_id
    INNER JOIN tasks ON employees_tasks.task_id = tasks.id
WHERE
    tasks.name LIKE 'Programming'

ここまでは順調ですが、「プログラミング」と「サポート」を担当するすべての従業員を取得したいと考えています。このクエリでは NULL が返されます。

SELECT employees.id, employees.name
FROM employees 
    INNER JOIN employees_tasks ON employees.id = employees_tasks.employee_id
    INNER JOIN tasks ON employees_tasks.task_id = tasks.id
WHERE
    tasks.name LIKE 'Programming' AND tasks.name LIKE 'Support'

このクエリで 3 つのレコードを受け取ります

SELECT employees.id, employees.name
FROM employees 
    INNER JOIN employees_tasks ON employees.id = employees_tasks.employee_id
    INNER JOIN tasks ON employees_tasks.task_id = tasks.id
WHERE
    tasks.name IN ('Programming', 'Support')

2x ジョンと 1x マイク。しかし、それは私が望むものではありません。「プログラミング」と「サポート」のタスクを持つすべての従業員が必要です。タスクの1つしか持たない従業員ではありません。

別のオプションがあります。サブクエリで ALL を使用します。どうぞ:

SELECT employees.id, employees.name
FROM employees 
    INNER JOIN employees_tasks ON employees.id = employees_tasks.employee_id
    INNER JOIN tasks ON employees_tasks.task_id = tasks.id
WHERE
    tasks.name = ALL
    (SELECT DISTINCT name
    FROM tasks
    WHERE name LIKE 'Programming' OR name LIKE 'Support')

しかし、両方のタスクを持っている従業員がいるにもかかわらず、このクエリで NULL を受け取ります: ジョン!

このようなクエリを実装するにはどうすればよいですか?

敬具クリスチャン

4

1 に答える 1

7

employees_tasksもう一度クエリに参加する必要があります。

SELECT employees.id, employees.name
FROM employees
  INNER JOIN employees_tasks AS et1 ON employees.id = et1.employee_id
  INNER JOIN employees_tasks AS et2 ON employees.id = et2.employee_id
  INNER JOIN tasks AS t1 ON et1.task_id = t1.id AND t1.name = 'Programming'
  INNER JOIN tasks AS t2 ON et2.task_id = t2.id AND t2.name = 'Support'

アップデート

または、関心のあるタスクのみの結果をフィルタリングする場合は、GROUP BY従業員を雇用して、目的のタスク数を持つ人のみを返すことができます。

SELECT   employees.id, employees.name
FROM     employees
  INNER JOIN employees_tasks ON employees_tasks.employee_id = employees.id
  INNER JOIN tasks           ON employees_tasks.task_id     = tasks.id
WHERE    tasks.name IN ('Programming', 'Support')
GROUP BY employees.id, employees.name
HAVING   COUNT(DISTINCT tasks.id) = 2
于 2012-05-10T11:45:59.413 に答える