使用JOIN关键字时添加两个条件是一个好习惯吗?

时间:2010-03-12 21:16:25

标签: sql tsql left-join

我想知道在使用JOIN关键字时是否需要条件是一个好习惯。

我正在尝试按日期过滤此结果集,但即使没有使用WHERE子句的日期的费用或收入,我也无法列出所有分支。有没有更好的方法,如果是这样的话?

SELECT
  Branches.Name
  ,SUM(Expenses.Amount) AS Expenses
  ,SUM(Incomes.Amount) AS Incomes
FROM
  Branches
  LEFT JOIN Expenses
    ON Branches.Id = Expenses.BranchId AND Expenses.Date = '3/11/2010'
  LEFT JOIN Incomes
    ON Branches.Id = Incomes.BranchId AND Incomes.Date = '3/11/2010'
GROUP BY Branches.Name

6 个答案:

答案 0 :(得分:5)

为什么不呢?更! OUTER JOIN对这两个条件有非常具体的伎俩!  INNER JOIN可以容忍重组,例如以下内容是等效的:

INNER JOIN Expenses
    ON Branches.Id = Expenses.BranchId
WHERE
    Expenses.Date = '3/11/2010'

通过:

INNER JOIN Expenses
    ON Branches.Id = Expenses.BranchId AND Expenses.Date = '3/11/2010'

BUT !!!对于OUTER JOIN,你必须在ON中准确指定两个条件,因为WHERE会将结果视为INNER JOIN

答案 1 :(得分:2)

这是调整外连接的正确方法。

只要您的查询可以对BranchIdDate表的ExpensesIncomes字段使用索引,就不会出现任何性能问题。< / p>

答案 2 :(得分:0)

你正确地做到了。在您的情况下,您希望过滤联接的右侧,因此日期条件属于联接。它说“给我所有的分支,只有那些符合我条件的收入和费用。”

当您将条件移至WHERE子句时,您将查询的整个含义更改为“给我所有分支及其收入和费用,但仅限于所有符合我条件的地方。”

这不是一个好的做法,而是设计数据库如何评估您的查询。

答案 3 :(得分:0)

这是使用外连接时执行此操作的最佳方法。将附加条件移动到where子句会将连接更改为内连接,因为它必须满足所有记录中的where条件。

答案 4 :(得分:0)

您的上述查询是正确的。以下是我如何保持直线:

  • 当条件在WHERE子句中时,它是一个必须在结果集中满足的条件,这意味着NULL行(例如,在LEFT JOIN中)将不匹配,并将被排除在外。
  • 如果条件在您的JOIN子句中(LEFT或RIGHT),则其标准必须在联接中满足,但不在结果中。如果存在一行,则它必须满足条件,但SQL将允许OUTER JOIN计为匹配,即使实际评估的另一侧没有值。

我不确定这是否更有意义,但是在你想要返回行的情况下,即使没有匹配,你的标准也必须在JOIN中(正如你上面所做的那样)。

答案 5 :(得分:-1)

我认为你应该将连接逻辑和过滤分开。

SELECT
  Branches.Name
  ,SUM(Expenses.Amount) AS Expenses
  ,SUM(Incomes.Amount) AS Incomes
FROM
  Branches
  LEFT JOIN Expenses
    ON Branches.Id = Expenses.BranchId
  LEFT JOIN Incomes
    ON Branches.Id = Incomes.BranchId
WHERE ISNULL(Expenses.Date,'3/11/2010') = '3/11/2010'
AND  ISNULL(Incomes.Date,'3/11/2010') = '3/11/2010'
GROUP BY Branches.Name