【问题标题】:SELECTing from other table with LEFT JOIN makes filtering not working使用 LEFT JOIN 从其他表中选择会使过滤不起作用
【发布时间】:2018-07-22 09:14:32
【问题描述】:

我有这个问题:

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 |
    +----+---------+------------+------+
    

我想通过其id、参与者的user_idrole 过滤掉request 数据。

当我像上面的例子一样运行查询时,它返回一行 (request.id = 10),但是如果我从查询中删除 COUNT(rt.id) total_task, IFNULL(SUM(IF(rt.status = 2, 1, 0)), 0) total_task_done 行,它返回零行,这就是我想要的.

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

【问题讨论】:

  • 嗨。您实际上并没有描述输出如何成为输入的函数。您希望我们可以从您的示例和错误的查询中猜到。说明在什么情况下一行会出现在您想要的结果中。如有必要或另外将输出描述为某个查询结果的函数,您会返回足够的数据。 “通过[某些字段]过滤掉数据”不清楚。如果您知道如何正确地从它转到当前所需的输出,请考虑询问更简单的所需输出。阅读 group by 和聚合如何工作——没有 group by 的聚合隐含地给出一个组。

标签: mysql left-join filtering where


【解决方案1】:

您需要在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

【讨论】:

  • 您确定将条件移至ON 子句吗?因为我试过你的,它仍然是一样的。并通过保持WHERE 的条件,它可以工作。
  • @RizkiPratama 因为您使用的是LEFT JOIN。如果您将条件放在表 request_participants 或 request_tasks 的 WHERE 子句中并且不匹配,它将不返回任何内容。这就像做INNER JOIN 一样。你能根据上面的记录显示样本输出吗?
【解决方案2】:

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

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2018-11-30
    • 1970-01-01
    • 2018-11-01
    • 2017-10-30
    • 1970-01-01
    • 2013-09-25
    相关资源
    最近更新 更多