3

我遇到了一个涉及 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

所需的输出是将两个金额相加,并为 Customer 和 Year 的每个唯一组合生成一行。

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 命令。但我得到的是交易金额值的重复,并且倍数与索赔表中匹配行的数量有关。

因此,使用我的示例数据,我得到以下信息:

Actual Output:
Customer | Year | Transaction Amount | Claim Amount
----------------------------------------------------
A        | 2007 | 200                | 70
A        | 2008 | 130                | NULL
A        | 2009 | 210                | 110

在 2007 年,有两个索赔导致 Transactions.Amount 值乘以 2(当有 3 个索赔时,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

答案是否存在于子查询中?我对他们不熟悉,所以任何指针都会很棒。谢谢。

4

3 回答 3

4

因此,查看发生情况的第一步是删除 SUM,然后选择交易金额和索赔金额。这样您就可以看到正在返回的数据。您将看到 A/2007 上的连接将有两次交易金额,因为它将每一行连接到索赔表。

一种解决方案是使用子查询,如您所说,在加入之前分别进行 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
于 2013-09-23T15:13:39.510 回答
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]
于 2013-09-23T15:21:28.190 回答
-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]
于 2013-09-23T15:18:19.193 回答