Sql server Sql Server使用聚合进行多个联接
我正在尝试修复继承代码中的一个错误。此查询旨在返回总计33美元的美国运通餐费,但它给出的是99美元。问题在于第二个联接-在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
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,而是结果应该是什么样子)?添加了表格结构和更多内容。谢谢