如何选择不同的行并交叉检查另一个表?

时间:2019-07-06 02:25:33

标签: php mysql join select union

我有3个表,userstaskscompleted_tasks。因此,基本上,我想选择user_id = 2处的所有任务,并还要检查该任务在另一个表中是否不存在`所以这是我的表:

users 表:

+----+-------+
| id | name  |
+----+-------+
|  1 | John  |
|  2 | Sally |
+----+-------+

tasks 表:

+----+-----------+---------+
| id | task_name | user_id |
+----+-----------+---------+
|  1 | mop floor |       2 |
|  2 | dishes    |       1 |
|  3 | laundry   |       2 |
|  4 | cook      |       2 |
+----+-----------+---------+

completed_tasks 表:

+----+---------+---------+
| id | task_id | user_id |
+----+---------+---------+
|  1 |       1 |       2 |
+----+---------+---------+

这是我当前用于MySQL数据库的SELECT代码:

$db = "SELECT DISTINCT tasks.task_name, users.name FROM tasks LEFT JOIN ON users.id = tasks.user_id WHERE tasks.user_id = 2";

我遇到的问题是:我希望它在completed_tasks表中进行搜索,如果任务存在,那么不要选择该任务。

我尝试通过添加以下内容来做到这一点,但是它没有用:

LEFT JOIN completed_tasks ON completed_tasks.user_id = 2

那是行不通的,因为如果我有多个已完成的任务,它将一并忽略。

我希望最终结果应返回任务3和4的用户名和任务名。

此外,在我的应用程序中,性能至关重要。我可以使用PHP并遍历数组,对每个数组进行SELECT,但这对性能不利。

1 个答案:

答案 0 :(得分:0)

您有几种方法可以做到这一点。

您可以使用LEFT JOIN,然后在可选表中检查NULL

SELECT a.name, b.task_name
FROM users a
JOIN tasks b ON a.id = b.user_id
LEFT JOIN completed_tasks c ON c.task_id = b.id AND c.user_id = b.user_id
WHERE c.id IS NULL
;

您可以进行NOT EXISTS子查询

SELECT a.name, b.task_name
FROM users a
JOIN tasks b ON a.id = b.user_id
WHERE NOT EXISTS (
    SELECT 1
    FROM completed_tasks c
    WHERE c.task_id = b.id AND c.user_id = b.user_id)
;