如何在 LEFT JOIN 上正确使用扩展约束,以便 return 左侧的所有结果

How to properly use extended constraints on a LEFT JOIN so as to return all results on the left side

我在将预算摘要视图从去年转换到今年时遇到问题。这是 SELECT 对去年观点的陈述,其中 return 是正确的:

SELECT 
    b.Category AS Category,
    b.Amount AS Amount,
    SUM(e.Amount) AS Spent,
    (b.Amount - SUM(e.Amount)) AS Remaining
FROM 
    Budget AS b LEFT JOIN Expenditure AS e 
    ON (
        b.Category = e.BudgetCategory
        AND e.Date < '2016-01-01'
        AND e.Date > '2015-01-01'
        AND b.Year = 2015
    )
GROUP BY e.BudgetCategory

如果我编辑日期使其包含今年,则会破坏视图,因为支出 table 中没有今年的记录。它只是 return 来自 Budget 的第一条记录,并且依赖于 Expenditure 的字段为 NULL。我想要的是 returned 预算中的所有记录,并为与依赖于支出的记录相关的所有字段列出 NULL。

去年的观点 returns:

Category    | Amount    | Spent     | Remaining
--------------------------------------------------------------
Contractors | 0.00      | NULL      | NULL (this is correct)
Gasoline    | 250.00    | 240.00    | 10.00
Merchandise | 2000.00   | 1900.00   | 100.00

等...

今年的return是什么:

Category    | Amount    | Spent | Remaining
--------------------------------------------
Contractors | 4000.00   | NULL  | NULL 

我想要的 return(支出结果保持为 0):

Category    | Amount    | Spent | Remaining 
--------------------------------------------
Contractors | 4000.00   | NULL  | NULL 
Gasoline    | 300.00    | NULL  | NULL 
Merchandise | 2500.00   | NULL  | NULL 

等...

我做错了什么?

您需要按 left joinfirst table 中的列进行聚合:

SELECT b.Category AS Category, b.amount,
       SUM(e.Amount) AS Spent,
       (b.Amount - SUM(e.Amount)) AS Remaining
FROM Budget b LEFT JOIN
     Expenditure e 
    ON b.Category = e.BudgetCategory AND
       e.Date < '2016-01-01' AND
       e.Date >= '2015-01-01'
       b.Year = 2015
GROUP BY b.Category, b.amount;

小改动:

  • 我将 ON 子句中的条件更改为 >=。只是看起来更合理。
  • 我将 b.amount 添加到 GROUP BY

这是一个小错误。您没有按 b.Category 分组,而是错误地按 e.BudgetCategory.

分组
SELECT 
    b.Category AS Category,
    b.Amount AS Amount,
    SUM(e.Amount) AS Spent,
    (b.Amount - SUM(e.Amount)) AS Remaining
FROM 
    Budget AS b LEFT JOIN Expenditure AS e 
    ON (
        b.Category = e.BudgetCategory
        AND e.Date < '2016-01-01'
        AND e.Date > '2015-01-01'
    )
WHERE b.Year = 2015
GROUP BY b.Category;

为了可读性,我将 b.Year 上的条件移到了 WHERE,因为它不是 Expenditure.

的外部连接的条件

顺便问一下,Category 是 table Budget 的唯一键吗?否则,您将获得任意选择的类别金额之一。也许您更想要一个聚合,例如 SUM(b.Amount)