将子查询转换为连接

时间:2017-01-16 06:26:23

标签: mysql sql join doctrine

我正在尝试通过联接转换下面的查询,

SELECT DISTINCT req.*
FROM request req
WHERE (req.user_id IN (
            SELECT id from user where id in (SELECT user_id FROM team_member team WHERE team.team_id IN ('344', '723')) and user.active = 1
)
OR req.user_id IN (
  SELECT id from user where id in (SELECT approved_employee_id from approver where approver_id = '269') and user.active = 1
))
   AND req.status = 'pending';

返回124条记录。

我通过联接写下面的查询,但不起作用,

SELECT DISTINCT req.*
FROM request req
  LEFT JOIN user u ON u.id = req.user_id AND u.active = 1
  LEFT JOIN team_member team ON team.user_id = u.id AND team.team_id IN ('344', '723')
  LEFT JOIN approver app ON app.approver_id = u.id AND app.approver_id = '269'
AND req.status = 'pending';

返回超过500条记录。

这个联接有两个问题,它包括状态未待决的那些请求。

以下是架构

我有以下表格

tbl_approver = 
id, 
approver_id (FK tbl_user), 
approver_team_id (FK tbl_team), 
approved_employee_id (FK tbl_user)

tbl_team_mambers = 
id, 
team_id (FK), 
user_id (FK)

tble_user = 
id, 
email, 
username
active


tbl_request = 
id, 
user_id, 
status
  • 团队成员:用户是多个团队的成员。
  • 审批人:
    • 每个团队都有一个审批人,他也是该团队的成员。
    • 无论团队如何,都可以直接批准员工。
  • 请求:用户的库存请求
  

注意:作为审批人,我可以成为许多团队的成员,但只有批准者   一些团队或者也是一些员工。

需要查询:作为审批人,我想要我批准的所有团队的请求。

2 个答案:

答案 0 :(得分:1)

要获得join的正确结果,您需要为任何连接的“表”返回user_id只有一行。如果只需要所有表中存在的行,请不要使用left

SELECT req.*
  FROM request req
  JOIN user ON user.id=req.user_id
  JOIN (
        SELECT distinct approved_employee_id as user_id from approver where approver_id = '269'
         UNION
        SELECT distinct user_id FROM team_member team WHERE team.team_id IN ('344', '723')
       ) A ON req.user_id=A.user_id
 where user.active = 1
   AND req.status = 'pending';

或者,如果只需要“真正的桌子”:

SELECT DISTINCT req.*
  FROM request req
  JOIN user u ON u.id = req.user_id AND u.active = 1
  LEFT JOIN team_member team ON team.user_id = u.id AND team.team_id IN ('344', '723')
  LEFT JOIN approver app  ON app.approver_id = u.id AND app.approver_id = '269'
 WHERE req.status = 'pending'
   AND (team.user_id is not null OR app.approver_id is not null)

答案 1 :(得分:0)

观看LEFT JOIN语法,此处为visual expression of joins

SELECT DISTINCT req.*
FROM request req
LEFT JOIN user u ON u.id = req.user_id AND u.active = 1
...

这将从request中选择所有不同的记录,并为用户选择JOIN个记录。 join_condition之后的ON只会影响联接关系。

  

如果LEFT JOIN中的ON或USING部分中的右表没有匹配的行,则将所有列设置为NULL的行用于右表。

Join syntax from Mysql Documentation

如果您确实想使用LEFT JOIN来过滤request的所有记录,请考虑将condition_expr移至WHERE

SELECT DISTINCT req.*
FROM request req
LEFT JOIN user u ON u.id = req.user_id
...
WHERE u.active = 1
AND ...

如果您只需要request满足用户的加入条件,则应考虑使用Join而不是LEFT JOIN