【问题标题】:How do I select distinct rows and cross check in another table?如何选择不同的行并在另一个表中交叉检查?
【发布时间】:2019-07-06 02:25:33
【问题描述】:

我有 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,但这对性能不利。

【问题讨论】:

  • 在描述中,您的tasks 表中没有assigned_to 列,而您的查询有,您的意思是user_id
  • @catcon 是的,很抱歉,我编辑了这篇文章。应该是user_id

标签: php mysql join select union


【解决方案1】:

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

您可以使用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)
;

【讨论】:

  • 谢谢,这可行,但与其他方式相比,这方面的表现如何?
  • 两者都会很快。数据库的执行计划在这些类型的查询中非常有效。您可以做的最糟糕的事情是将部分结果加载到 PHP 中,然后执行其他查询来获取/过滤数据。让数据库在单个查询中为您执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
  • 2018-01-21
相关资源
最近更新 更多