【问题标题】:LEFT JOIN gives different result when changing the location of condition [duplicate]更改条件位置时,LEFT JOIN 给出不同的结果[重复]
【发布时间】:2022-07-06 21:46:31
【问题描述】:

我有这个问题:

SELECT
    bc.name,
    SUM(amount) AS total
FROM
    budget_categories bc
LEFT JOIN budget_items bi ON
    bc.id = bi.budget_category_id
LEFT JOIN balance_lines bl ON
    bl.budget_item_id = bi.id
WHERE
    bc.id = 25 AND family_id = 97109 AND bl.balance_id = 264553

结果是:

NULL | NULL

但是当我将条件放在 LEFT JOIN 部分时,它可以工作:

SELECT
    bc.name,
    SUM(amount) AS total
FROM
    budget_categories bc
LEFT JOIN budget_items bi ON
    bc.id = bi.budget_category_id
LEFT JOIN balance_lines bl ON
    bl.budget_item_id = bi.id  AND family_id = 97109 AND bl.balance_id = 264553
WHERE
    bc.id = 25

结果是:

Bannana | NULL

为什么会有差异?

【问题讨论】:

标签: mysql left-join


【解决方案1】:

当您使用outer join(例如左外连接)时,您要求查询返回行,即使该表没有完全匹配也是如此。因此,左外连接列可能存在 NULL 值。

在第一个 where 子句中,您要求整个结果行中的每一行都具有 bl.family_id = 97109 AND bl.balance_id = 264553 但这里所有返回的行都必须具有 NULL bc.name 和 NULL 数量。 (顺便说一句:这有时被称为隐式内部连接,实际上相当于下面的查询:)

选择 bc.name, SUM(金额) 总计 从 预算类别 bc 左加入 budget_items bi ON bc.id = bi.budget_category_id INNER JOIN balance_lines bl ON -- where 子句有这个效果 bl.budget_item_id = bi.id 在哪里 bc.id = 25 AND bl.family_id = 97109 AND bl.balance_id = 264553

在第二个查询中,您只允许 balance_lines 的行受到连接条件的限制,以便可以从其他表中重新调整更多行 - 在这些额外的行中,您会获得香蕉的 bc.name。

使用左连接时,如果要允许返回 NULL,则必须注意引用外部连接表的任何谓词,例如

SELECT
    bc.name,
    SUM(amount) AS total
FROM
    budget_categories bc
LEFT JOIN budget_items bi ON
    bc.id = bi.budget_category_id
LEFT JOIN balance_lines bl ON
    bl.budget_item_id = bi.id
WHERE
    bc.id = 25 
    AND (bl.family_id = 97109 OR bl.family_id IS NULL)
    AND (bl.balance_id = 264553 OR bl.balance_id IS NULL)

修改后的 where 子句的行为与您现在的第二个查询一样。

【讨论】:

    猜你喜欢
    • 2014-10-18
    • 2015-03-10
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多