Sql server Sql Server使用聚合进行多个联接

Sql server Sql Server使用聚合进行多个联接,sql-server,left-join,aggregate-functions,Sql Server,Left Join,Aggregate Functions,我正在尝试修复继承代码中的一个错误。此查询旨在返回总计33美元的美国运通餐费,但它给出的是99美元。问题在于第二个联接-在EE表中有三个相关项,这使得聚合汇总为三行 SELECT ER.report_id, Isnull(Sum(EE_AMEX.meal_amount), 0) AS amex_meal_amount_total FROM expense_report ER (nolock) LEFT OUTER JOIN expense_expense EE_A

我正在尝试修复继承代码中的一个错误。此查询旨在返回总计33美元的美国运通餐费,但它给出的是99美元。问题在于第二个联接-在
EE表中有三个相关项
,这使得聚合汇总为三行

SELECT ER.report_id,
       Isnull(Sum(EE_AMEX.meal_amount), 0) AS amex_meal_amount_total
FROM   expense_report ER (nolock)
       LEFT OUTER JOIN expense_expense EE_AMEX (nolock)
                    ON ER.report_id = EE_AMEX.report_id
                       AND EE_AMEX.line_item_type_id = 1
       LEFT OUTER JOIN expense_expense EE_OOP (nolock)
                    ON ER.report_id = EE_OOP.report_id
                       AND EE_OOP.line_item_type_id = 2
WHERE  er.report_id = 9733
GROUP  BY ER.report_id  
我很清楚,开发人员试图在联接中使用表别名(例如EE_AMEX),以将
sum
函数限制为联接中的条件

对于此
id
,在
EE表中只有一行具有
line\u item\u type\u id 1
。当我删除另一个join语句时,它会返回预期的
$33

 SELECT ER.report_id,
       Isnull(Sum(EE_AMEX.meal_amount), 0) AS amex_meal_amount_total
FROM   expense_report ER (nolock)
       LEFT OUTER JOIN expense_expense EE_AMEX (nolock)
                    ON ER.report_id = EE_AMEX.report_id
                       AND ee_oop.line_item_type_id = 1
WHERE  er.report_id = 9733
GROUP  BY ER.report_id  
是否有一个简单的解决方法,或者我需要完全重新构造查询

表结构:

这个问题要尽量简单

费用报告:
报告id(主键)

费用\u费用
报告id(FK,一对多)
餐费金额(可以是多行,每个报告\u id包含餐费金额)
出租车费金额(其他费用示例)
行\项目\类型\ id(1为美国运通,2为OOP,每行可以任意)

在这种情况下,急诊室有一行相关的费用支出,餐费为33美元,这就是我所期望的

然而,其他费用(如出租车等)有三个相关行

当运行查询时,它将其相加三行,从而得到意外的$99


谢谢。

总和
移动到
子查询
中如何?您可能需要对您的
EE_OOP聚合执行相同的操作,但我不确定您从中得到了什么

 SELECT ER.report_id,
       Isnull((SELECT Sum(meal_amount)
               FROM   expense_expense EE_AMEX (nolock)
               WHERE  EE_AMEX.report_id = ER.report_id
                      AND EE_AMEX.line_item_type_id = 1), 0) AS
       amex_meal_amount_total
FROM   expense_report ER (nolock)
       LEFT OUTER JOIN expense_expense EE_OOP (nolock)
                    ON ER.report_id = EE_OOP.report_id
                       AND EE_OOP.line_item_type_id = 2
WHERE  er.report_id = 9733  

如果您正在寻找第一个查询返回$99的原因,那么让我们看看如何返回。 让表定义为

select 1 report_id into #expense_report;

select * into #expense_expense from (
select 1 report_id, 33 meal_amount, 0 taxi_amount, 1 line_item_type_id
union all
select 1 report_id, 0 meal_amount, 33 taxi_amount, 2 line_item_type_id
union all
select 1 report_id, 0 meal_amount, 33 taxi_amount, 2 line_item_type_id) t;
因此,在第一次离开费用表后,结果将是一行

SELECT *
FROM   #expense_report ER (nolock)
       LEFT OUTER JOIN #expense_expense EE_AMEX (nolock)
                    ON ER.report_id = EE_AMEX.report_id
                       AND EE_AMEX.line_item_type_id = 1
WHERE  er.report_id = 1;

report_id   report_id   meal_amount taxi_amount line_item_type_id
1               1         33            0             1
现在,第二个左连接将应用于此结果,即,将单行连接到双行结果,这将导致两行

SELECT *
FROM   #expense_report ER (nolock)
       LEFT OUTER JOIN #expense_expense EE_AMEX (nolock)
                    ON ER.report_id = EE_AMEX.report_id
                       AND EE_AMEX.line_item_type_id = 1
       LEFT OUTER JOIN #expense_expense EE_OOP (nolock)
                    ON ER.report_id = EE_OOP.report_id
                       AND EE_OOP.line_item_type_id = 2
WHERE  er.report_id = 1;

report_id   report_id   meal_amount taxi_amount line_item_type_id   report_id   meal_amount taxi_amount line_item_type_id
1   1   33  0   1   1   0   33  2
1   1   33  0   1   1   0   33  2
请注意这些列。第一个表的进餐量重复,因为它与右表的两行连接。 因此,在这一点上的总和将导致66美元,而不是33美元

如果您想在一行不同的列中同时显示出租车和餐费金额,请使用以下查询:

SELECT ER.report_id,
       Isnull(Sum(case when EE_AMEX.line_item_type_id  =1 then EE_AMEX.meal_amount end), 0) AS amex_meal_amount_total,
       Isnull(Sum(case when EE_AMEX.line_item_type_id  =2 then EE_AMEX.taxi_amount end), 0) AS amex_taxi_amount_total
FROM   #expense_report ER (nolock)
       LEFT OUTER JOIN #expense_expense EE_AMEX (nolock)
                    ON ER.report_id = EE_AMEX.report_id
WHERE  er.report_id = 1
GROUP  BY ER.report_id

为什么在没有使用该表的情况下加入oop?第一个查询中的左连接类似于ER.report\u id=EE\u AMEX.report\u id和(EE\u oop.line\u item\u type\u id=1或EE\u oop.line\u item\u type\u id=2)。您在第二次查询中得到了结果。@Giorgi Nakeuri,出于示例目的,我没有包含完整的查询,它也从EE_OOP检索聚合。感谢您提供表格结构、当前结果集和预期结果集(不是99和33,而是结果应该是什么样子)?添加了表格结构和更多内容。谢谢