我遇到涉及SUM,LEFT OUTER JOIN和GROUP BY命令的问题,但无法弄清楚我的错误在哪里。
我有两个表,一个用于客户交易,一个用于客户索赔。客户可以拥有多个交易和多个索赔,但在两个表中,行都是唯一的。客户也可以没有索赔。
交易表示例:
Transactions:
Customer | Transaction Year | Amount
-------------------------------------
A | 2007 | 100
A | 2008 | 80
A | 2008 | 50
A | 2009 | 210
索赔表示例:
Claims:
Customer | Claim Year | Amount
-------------------------------
A | 2007 | 30
A | 2007 | 40
A | 2009 | 110
所需的输出是对两个金额求和,并为每个客户和年份的唯一组合生成一行。
Desired Output:
Customer | Year | Transaction Amount | Claim Amount
----------------------------------------------------
A | 2007 | 100 | 70
A | 2008 | 130 | NULL
A | 2009 | 210 | 110
我使用了一个带有GROUP BY命令的LEFT OUTER JOIN命令作为Customer和Year值。但我得到的是Transaction Amount值的重复,并且倍数与Claims表中匹配行的数量有关。
因此,使用我的示例数据,我得到以下内容:
Actual Output:
Customer | Year | Transaction Amount | Claim Amount
----------------------------------------------------
A | 2007 | 200 | 70
A | 2008 | 130 | NULL
A | 2009 | 210 | 110
在2007年,有两个声明导致Transactions.Amount值乘以2(当有三个声明时,Transaction.Amount三倍,等等。)
我的代码如下:
SELECT Transactions.Customer,
Transactions.Year,
sum(Transactions.Transaction Amount),
sum(Claims.Claim Amount)
FROM Transactions
LEFT JOIN Claims ON Claims.Customer = Transactions.Customer
AND Transactions.Year = Claims.Year
GROUP BY Transactions.Customer, Transactions.Year
答案是否在子查询中?我不熟悉它们,所以任何指针都会很棒。感谢。
答案 0 :(得分:4)
因此,查看正在发生的事情的第一步是删除SUM,只需选择交易金额和索赔金额。这样您就可以看到返回的数据。您将看到A / 2007上的联接将具有两次交易金额,因为它将每一行都连接到索赔表。
一种解决方案是使用subquerys,就像你说的那样,在加入之前单独进行SUM。
SELECT
Transactions.Customer,
Transactions.Year,
SumTransaction,
SumClaim
FROM (
select Customer, Year, sum(Transaction Amount) SumTransaction
from Transactions
group by Customer, Year
) Transactions
LEFT JOIN (
select Customer, Year, sum(Claim Amount) sumClaim
from Claims
group by Customer, Year
) Claims
ON Claims.Customer = Transactions.Customer
AND Transactions.Year = Claims.Year
根据您的限制,另一种可能的解决方案:
SELECT
Transactions.Customer,
Transactions.Year,
SUM(Transaction Amount),
(SELECT SUM(Claim Amount) from Claims where Claims.Customer = Transactions.Customer and Claims.Year = Transactions.Year)
FROM
Transactions
GROUP BY
Customer, Year
第三种可能的解决方案!!这个不需要任何子查询!见SQL Fiddle
select
t.Customer,
t.Year,
sum(distinct t.Amount),
sum(c.Amount)
from
Transactions t
left join Claims c
on t.Customer = c.Customer
and t.Year = c.year
group by
t.Customer,
t.Year
答案 1 :(得分:0)
由于您有两项索赔,查询将在2007年两次计算交易金额,因此交易金额将被计算两次。
即。使用的返回数据是:
Customer | Transaction Year | Transaction Amount | Claim Amount
----------------------------------------------------------------
A | 2007 | 100 | 30
A | 2007 | 100 | 40
A | 2008 | 80 |
A | 2008 | 50 |
A | 2009 | 210 | 110
如下所示,虽然不是很漂亮,但应解决问题:
SELECT
t.Customer
,t.Year
,[Transaction Amount] = SUM(t.[Transaction Amount])
,[Claim Amount] = c.[Claim Amount]
FROM
Transactions t
LEFT JOIN (
SELECT
Customer
,Year
,SUM([Claim Amount])
FROM
Claims
GROUP BY
Customer, Year
) c ON c.Customer = t.Customer c.Year = t.Year
GROUP BY t.Customer, t.Year, c.[Claim Amount]
答案 2 :(得分:-1)
With T as (
SELECT Customer,
[Transaction Year],
sum(Amount) AS TransactionAmount
FROM Transactions
GROUP BY Customer, [Transaction Year]
), C AS
SELECT Customer,
[Claim Year],
sum(Amount) as ClaimAmount
FROM Claims
GROUP BY Customer, [Claim Year]
)
SELECT T.Customer,
[Transactions Year],
TransactionAmount,
ClaimAmount
FROM T
LEFT JOIN C ON C.Customer = T.Customer
AND [Transactions Year] = [Claim Year]