繁体   English   中英

将子查询转换为联接

[英]Convert Sub-query into Joins

我试图通过联接转换下面的查询,

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
  • 团队成员:用户是多个团队的成员。
  • 批准人:
    • 每个团队都有一个批准人,该批准人也是该团队的成员。
    • 无论团队如何,都可以直接批准员工。
  • request:用户的库存请求

注意:作为批准者,我可以是许多团队的成员,但只能是某些团队的批准者。 还是一些员工。

想要查询:作为批准者,我希望批准我的团队的所有请求。

为了获得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)

观看LEFT JOIN语法,这是联接直观表达

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

这将选择所有不重复的记录request ,并JOIN他们的用户。 ON之后的join_condition将仅影响join_condition关系。

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

来自Mysql文档的联接语法

如果您确实想使用LEFT JOIN过滤request所有记录, 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM