1

我通常采用这种join方法,但在这种情况下我有点困惑。我什至不确定这是否可能。我想知道是否可以将以下查询转换为left join查询而不是使用多个select in

select 
   users.id, users.first_name, users.last_name, users.description, users.email 
from users 
where id in (
     select assigned.id_user from assigned where id_project in (
            select assigned.id_project from assigned where id_user = 1
                                                               )
            ) 
   or id in (
     select projects.id_user from projects where projects.id in (
            select assigned.id_project from assigned where id_user = 1
                                                                )
            )  

此查询返回正确的结果集。但是,我想重复选择的查询assigned.id_project是一种浪费。

4

3 回答 3

4

您可以从用户 1 的项目分配开始a1。然后找到其他人对这些项目的所有分配a2,以及项目表中的用户p。然后,您要查找的用户位于a2p中。我添加了 distinct 以删除可以通过两种方式访问​​的用户。

select  distinct u.*
from    assigned a1
left join    
        assigned a2
on      a1.id_project = a2.id_project
left join
        project p
on      a1.id_project = p.id
join    user u
on      u.id = a2.id_user
        or u.id = p.id_user
where   a1.id_user = 1
于 2012-10-27T10:29:42.603 回答
3

由于两个子查询都具有assigned.id_user = 1 的条件,因此我从该查询开始。让我们称该任务为“主要任务”。

然后加入其余部分,对“可选”表使用左连接。user使用与链接到主要任务的任务用户或链接到主要项目的项目用户匹配的内部连接。

我使用 distinct,因为我假设您希望每个用户一次,如果他们有一个任务和一个项目(或多个项目)。

select distinct
  u.id, u.first_name, u.last_name, u.description, u.email 
from 
  assigned a
  left join assigned ap on ap.id_project = a.id_project
  left join projects p on p.id = a.id_project
  inner join users u on u.id = ap.id_user or u.id = p.id_user
where
  a.id_user = 1
于 2012-10-27T10:21:14.533 回答
2

这是摆脱重复的另一种方法:

SELECT
  users.id,
  users.first_name,
  users.last_name,
  users.description,
  users.email 
FROM users
WHERE id IN (
  SELECT up.id_user
  FROM (
    SELECT id_user, id_project FROM assigned
    UNION ALL
    SELECT id_user, id         FROM projects
  ) up
  INNER JOIN assigned a
    ON a.id_project = up.id_project
  WHERE a.id_user = 1
)
;

也就是说,assigned表的 对与 的对id_user, id_project是联合的projects。然后将结果集与user_id = 1项目连接,以获得与 ID 1 用户共享项目的所有用户的列表。现在只剩下检索这些用户的详细信息了,在这种情况下,这与查询中的方式相同,即使用 IN 子句。

很抱歉,我没有 MySQL 来彻底测试此查询的性能,因此无法确定它是否比您的原始查询更好或更差,或者比@GolezTrol通过@Andomar。一般来说,我倾向于同意@GolezTrol 的评论,即具有简单(半或其他)连接和重复部分的查询可能比没有重复的等效复杂查询更有效。然而,最终,测试必须为您揭示最终答案。

于 2012-10-27T13:09:08.803 回答