Question

I have three MySQL tables with many-to-many relationship.

One table is for tasks, another is for users, and the third is for assigning tasks to users (each task can be assigned to several users).

users:           tasks:            assigned:
+----+------+    +----+-------+    +---------+---------+
| id | name |    | id | title |    | task_id | user_id |
+----+------+    +----+-------+    +---------+---------+
| 1  | John |    | 1  | One   |    |    1    |    1    |
+----+------+    +----+-------+    +---------+---------+
| 2  | Mike |    | 2  | Two   |    |    1    |    2    |
+----+------+    +----+-------+    +---------+---------+
                                   |    2    |    1    |
                                   +---------+---------+

How do I get tasks assigned to only one user?

How do I get tasks assigned to only one particular user?

Was it helpful?

Solution

You need to join all tables together. Use the following to show all tasks assigned to John:

SELECT name,title
FROM users
JOIN assigned ON (user_id=users.id)
JOIN tasks ON (tasks.id=task_id)
WHERE name="John";

Use GROUP BY and HAVING to see all tasks that were only assigned to one user.

SELECT title 
FROM tasks
JOIN assigned ON (task_id=id)
GROUP BY id
HAVING count(*) = 1;

In latter you don't necessarily need to know to who tasks were assigned to, just that they were only assigned to one user. Therefore you don't need to join users table.

Update:

You can use the following to find tasks assigned to John alone:

SELECT name,title 
 FROM tasks
  JOIN assigned ON (task_id=tasks.id)
  JOIN users ON (user_id=users.id)
 GROUP BY tasks.id
 HAVING COUNT(*) = 1 and name="John";

This is possible due to two reasons:

  1. MySQL allows non-aggregated references in HAVING clause.
  2. COUNT(*)=1 forces name to be single value - i.e. you are not in a situation where name would have both 'John' and 'Mike'.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top