Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在左侧联接上正确使用扩展约束,以便在左侧返回所有结果_Mysql_Sql_Left Join - Fatal编程技术网

Mysql 如何在左侧联接上正确使用扩展约束,以便在左侧返回所有结果

Mysql 如何在左侧联接上正确使用扩展约束,以便在左侧返回所有结果,mysql,sql,left-join,Mysql,Sql,Left Join,我无法将去年的预算摘要视图转换为今年的预算摘要视图。以下是去年视图的SELECT语句,它返回正确的内容: 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 (

我无法将去年的预算摘要视图转换为今年的预算摘要视图。以下是去年视图的SELECT语句,它返回正确的内容:

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

今年的回报情况:

Category    | Amount    | Spent | Remaining
--------------------------------------------
Contractors | 4000.00   | NULL  | NULL 
我希望它返回的内容(而支出结果仍然为0):

等等


我做错了什么?

您需要按左联接的第一个表中的列进行聚合:

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;
选择b.类别作为类别,b.金额,
已花费的金额(如金额),
(b.金额-剩余金额(e.金额))
从预算b左连接
支出e
b.类别=e.预算类别和
e、 日期<'2016-01-01'和
e、 日期>='2015-01-01'
b、 年份=2015年
按b.类别、b.金额分组;
小变化:

  • 我将
    ON
    子句中的条件更改为
    =
    。这似乎更合理
  • 我将
    b.amount
    添加到
    分组中

您需要按
左联接的第一个表中的列进行聚合

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;
选择b.类别作为类别,b.金额,
已花费的金额(如金额),
(b.金额-剩余金额(e.金额))
从预算b左连接
支出e
b.类别=e.预算类别和
e、 日期<'2016-01-01'和
e、 日期>='2015-01-01'
b、 年份=2015年
按b.类别、b.金额分组;
小变化:

  • 我将
    ON
    子句中的条件更改为
    =
    。这似乎更合理
  • 我将
    b.amount
    添加到
    分组中

  • 这是一个小错误。您没有按
    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、 类别作为类别,
    b、 金额作为金额,
    已花费的金额(如金额),
    (b.金额-剩余金额(e.金额))
    从…起
    预算为b左,支出为e
    在(
    b、 类别=e.BudgetCategory
    和e.日期<'2016-01-01'
    和e.日期>'2015-01-01'
    )
    其中b.年份=2015年
    按b类分组;
    
    为了可读性,我将
    b.Year
    上的标准移动到
    WHERE
    ,因为它不是
    支出的外部联接的标准


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

    这是一个小错误。您没有按
    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、 类别作为类别,
    b、 金额作为金额,
    已花费的金额(如金额),
    (b.金额-剩余金额(e.金额))
    从…起
    预算为b左,支出为e
    在(
    b、 类别=e.BudgetCategory
    和e.日期<'2016-01-01'
    和e.日期>'2015-01-01'
    )
    其中b.年份=2015年
    按b类分组;
    
    为了可读性,我将
    b.Year
    上的标准移动到
    WHERE
    ,因为它不是
    支出的外部联接的标准


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

    是表
    预算的唯一键(可能是主键)
    吗?或者对于同一
    类别
    ,是否会有多条
    预算
    记录?
    类别
    是否是表
    预算
    的唯一键(可能是主键)?或者同一个
    类别可以有多个
    预算
    记录
    ?我发现查询也可以通过按e.BudgetCategory和b.Category分组或仅按b.Category分组来工作。我最初是按e.BudgetCategory进行分组的,因为e表中的内容正在汇总。这里对逻辑的高层次解释是什么。为什么group by需要位于联接的任何一侧?@Shadouts:这是因为您要联接外部支出表。如果在该表中找不到给定日期范围内Budget.Category的匹配项,则会得到一条所有字段均为空的伪记录,包括BudgetCategory。所以你没有按你实际查找的类别(Budget.category)分组。@Shadouts:至于“按e.BudgetCategory和b.category分组,或者仅按b.category分组”,这是因为正如你在对我的回答的评论中所说,一年中每个类别只有一个记录。如果不是这样的话,你会得到一个类别的金额任意选择。Gordon不知道category+year在您的表中是唯一的,所以他将budget.amount放在GROUP BY子句中,以确保不会悄悄地引入这样的错误。此外,在GROUPBY中包含此列可以保证查询在MySQL中仅在打开_FULL_GROUP_BY模式的情况下运行;我发现查询也可以通过按e.BudgetCategory和b.Category分组,或者仅按b.Category分组。我最初是按e.BudgetCategory进行分组的,因为e表中的内容正在汇总。这里对逻辑的高层次解释是什么。为什么group by需要位于联接的任何一侧?@Shadouts:这是因为您要联接外部支出表。如果在该表中找不到给定日期范围内Budget.Category的匹配项,则会得到一条所有字段均为空的伪记录,包括BudgetCategory。所以你没有按你实际查找的类别(Budget.category)分组。@Shadouts:至于“按e.BudgetCategory和b.category分组,或者仅按b.category分组”,这是因为正如你在对我的回答的评论中所说,一年中每个类别只有一个记录。如果不是这样的话,你会得到一个类别的金额