MySQL 从 2 个表中进行 SELECT 查询产生不一致的结果

问题描述 投票:0回答:1

我对 SQL 还很陌生,我觉得我让这件事变得比实际需要的更加困难。希望有人能指出我正确的方向。

目标是返回一组可用用户,这些用户被分配到我们正在处理的站点,并且可以执行我们想要分配的任务。

对于这个问题,我们可以假设我们正在处理 site_id 4 并且我们正在尝试分配 task_id 2

我们的桌子是:

Table: site_tasks_assignments

id | user_id | site_id | task_id | complete
--------------------------------------------
12 | 6       | 4       | 2       | 1
13 | 4       | 3       | 2       | 0
14 | 2       | 4       | 3       | 0
15 | 6       | 4       | 4       | 1


Table: users

id | name    | site_id 
-----------------------
1  | bob     | 1
2  | henry   | 4
3  | jane    | 2
4  | mary    | 3
5  | kyle    | 4
6  | steve   | 4

如果满足以下条件,用户应出现在结果中:

  • users.site_id
    = 我们正在工作的站点的 ID(再次假设
    site_id
    4)

并且,以下任意一项为真:

  • users.id
    根本没有出现在
    site_task_assignments.user_id
    中,这意味着他们在任何站点都没有被分配任何任务,
  • 用户位于
    site_task_assignments
    表中,但 尚未被分配该特定任务(在本例中为
    task_id
    2),
  • 用户位于
    site_task_assignments
    表中并且 被分配了该特定任务并且该行的
    site_task_assignments.complete
    列为 1

考虑到上述参数,我期望的结果是:

id | name    | site_id 
-----------------------
2  | henry   | 4   <- not assigned to task 2, can work on site 4
5  | kyle    | 4   <- not assigned to any tasks, can work on site 4
6  | steve   | 4   <- WAS assigned to task 2, task 2 complete, can do task 2 again, can work on site 4

我尝试了几个版本的查询,其中一些涉及某种 JOIN,还有一些涉及子查询等。我得到的最接近的是:

SELECT u.*, sta.task_id, sta.user_id, sta.complete FROM users as u
LEFT JOIN site_task_assignments as ci ON u.id = sta.user_id
WHERE u.site_id = 4
AND (u.id NOT IN (SELECT user_id FROM site_task_assignments)
OR (u.id IN (SELECT user_id FROM site_task_assignments) AND sta.task_id = 2 AND complete = 1)
OR (u.id IN (SELECT user_id FROM site_task_assignments) AND (sta.task_id = 2 AND complete = 1 OR sta.task_id != 2 AND complete = 0)))

这给了我不一致的结果。在某些任务上,这很好,在已分配的其他任务上,它有时会向我提供用户已分配给任务但完成度为 0 的信息。在根本未分配的任务上,它会向我提供重复的任务如果他们已经在其他任务的

site_task_assignments
表中,则为同一用户。

mysql select left-join
1个回答
0
投票

试试这个:

select distinct u.id as id,name, u.site_id as site_id 
from users u
left join site_tasks_assignments s
on u.id=s.user_id 
where u.site_id=4 and (s.user_id is null 
                        or not exists (select 1 from  site_tasks_assignments 
                                        where site_tasks_assignments.user_id=s.user_id and site_tasks_assignments.task_id =2)
                        or exists (select 1 from  site_tasks_assignments 
                                        where site_tasks_assignments.user_id=s.user_id and site_tasks_assignments.task_id =2 and complete=1)
                        )
;
© www.soinside.com 2019 - 2024. All rights reserved.