使用LEFT JOIN从其他表中选择使过滤无效

时间:2018-02-12 08:44:54

标签: mysql left-join filtering where

我有这个问题:

SELECT 
    r.*, 
    COUNT(rt.id) total_task, 
    IFNULL(SUM(IF(rt.status = 2, 1, 0)), 0) total_task_done
FROM requests AS r
LEFT JOIN request_participants AS rp ON rp.request_id = r.id
LEFT JOIN request_tasks AS rt ON rt.request_id = r.id
WHERE r.id = 10 AND rp.user_id = 3 AND rp.role = 1

这些是包含数据的表格:

  • requests

    +----+-----------------+--------+
    | id |      notes      | status |
    +----+-----------------+--------+
    | 10 | Some notes here |      1 |
    +----+-----------------+--------+
    
  • request_participants

    +----+---------+------------+------+
    | id | user_id | request_id | role |
    +----+---------+------------+------+
    | 18 |       3 |         10 |    0 |
    | 19 |      17 |         10 |    1 |
    +----+---------+------------+------+
    

我希望通过request,参与者的iduser_id过滤掉role数据。

当我以与上面的示例完全相同的方式运行查询时,它返回一行(request.id = 10),但如果我从查询中删除COUNT(rt.id) total_task, IFNULL(SUM(IF(rt.status = 2, 1, 0)), 0) total_task_done行,则返回零行,这是我想要的。

你能帮我指出我的查询有什么问题吗?谢谢。

2 个答案:

答案 0 :(得分:0)

您需要在ON子句中移动条件,以便在实际连接之前进行过滤并添加GROUP BY子句。

SELECT  r.ID, r.notes, r.status, 
        COUNT(rt.id) total_task, 
        IFNULL(SUM(IF(rt.status = 2, 1, 0)), 0) total_task_done
FROM    requests AS r
        LEFT JOIN request_participants AS rp 
            ON rp.request_id = r.id
                AND rp.user_id = 3
                AND rp.role = 1
        LEFT JOIN request_tasks AS rt 
            ON rt.request_id = r.id
WHERE   r.id = 10 
GROUP   BY r.ID, r.notes, r.status

答案 1 :(得分:0)

然后对各个表进行过滤,然后进行连接和聚合。试试这个:

SELECT  A.id, A.notes, A.status, 
    SUM(IF(C.id IS NULL, 0, 1)) total_task, 
    IFNULL(SUM(IF(C.status = 2, 1, 0)), 0) total_task_done
FROM (SELECT * FROM requests 
WHERE id = 10) A LEFT JOIN
(SELECT * FROM request_participants WHERE user_id = 3 AND role = 1) B 
 ON A.id=B.request_id LEFT JOIN
 request_tasks C 
 ON A.id=C.request_id
 GROUP BY A.id,  A.notes,  A.status;