我试图修复继承代码中的错误。此查询旨在带回amex_meal_amount_total of $33
,但它正在提供$99
。问题在于第二次加入 - EE table
中有三个关联项目使汇总总和达到三行。
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
函数限制为连接中的条件。
此EE table
的{{1}}只有一行line_item_type_id 1
。当我删除其他连接语句时,它会带回预期的ID
。
$33
是否有直接的解决方法,或者我是否需要完全重构查询?
表格结构:
试图让这个问题变得简单
expense_report:
report_id(PK)
expense_expense :
report_id(FK,一对多)
meal_amount(可以是每行report_id的多行膳食量)
taxi_amount(其他费用的例子)
line_item_type_id(1是AMEX,2是OOP,每行可以是任何一个)
在这种情况下,ER在expense_expense中有一个相关的行,用餐费为33美元,这就是我所期望的。
然而,其他收费有三个相关行,例如出租车等。
运行查询时,它会将其总计为三行,因此意外的$ 99。
感谢。
答案 0 :(得分:1)
如何将sum
转换为subquery
呢?您可能需要为EE_OOP aggregate
执行相同的操作,但我不确定您从中获取了什么。
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
答案 1 :(得分:1)
如果您正在寻找为什么第一个查询返回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
现在第二个左连接将应用于此结果,即单行连接到双行结果,这将产生2行。
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
注意列。第一个表的meal_amount重复,因为它正在连接右表的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