当前位置: 首页 > 知识库问答 >
问题:

涉及求和、左联接和分组方式的复制

秦阳旭
2023-03-14

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

对于客户值和年份值,我使用了一个LEFT-OUTER-JOIN命令和一个GROUP-BY命令。但我得到的是交易金额值的一个副本,该倍数与索赔表中匹配行的数量有关。

因此,使用我的示例html" target="_blank">数据,我得到以下结果:

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

在2007年,有两项索赔导致了交易。金额值乘以2(当有三项索赔时,交易。金额增加三倍,以此类推)。

我的代码如下:

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

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

共有3个答案

萧明贤
2023-03-14
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]
孔阳炎
2023-03-14

由于您有两个索赔,查询将对2007年的交易金额进行两次计数,因此交易金额将被计数两次。

i、 e.正在使用的返回数据是:

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]
濮阳宜
2023-03-14

因此,了解发生了什么的第一步是删除SUM,只需选择交易金额和索赔金额。这样,您可以看到返回的数据。您将看到A/2007上的连接将有两次事务金额,因为它将每行连接到声明表。

一种解决方案是使用子查询,如您所说,在加入之前分别进行求和。

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小提琴

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
 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : SQL中左右联结与左右联结之间的区别[重复] (4个答案) 6年前关闭。 我看到过称为LEFT OUTER JOIN或RIGHT OUTER JOIN的联接。在某些地方,我见过LEFT JOIN或RIGHT JOIN。我对此感到困惑。 我两天前发布了一个问题,但我无法理解解决方案提供的链接。 这些连接类型是否相同,或者两者之间有区别? 问题答案: 两者之

  • 我有3张表<br>Tbcodetable<br> Tbmember TB存款< br > 我想在一个查询中查询每个sato的资本和储蓄的总和 我能做的最好的查询是 这给了我这个结果。 这只给了我资本的总和(我迷失了如何包括储蓄和资本的结果),它不包括那牙地区 。 我可以通过employeeno连接tbmember和tbdeposit,但是我不知道如何在结果集中分离资本和储蓄的总和 编辑< br >

  • 问题内容: 我正在尝试创建一个更新查询,并且在获取正确的语法方面进展甚微。以下查询正在运行: 它创建一个三元组的列表Index1,Index2,EventCounts。仅在t.SpecialEventCount为NULL的情况下才这样做。我尝试编写的更新查询应将此SpecialEventCount设置为该计数,即上述查询中的COUNT(m.EventType)。此数字可以是0或任何正数(因此为左联

  • 问题内容: 我有两张桌子。表A列出了员工姓名。表B是一个复杂的表,其中包含有关员工打来的电话的信息。 我的目标是制作一个包含“名称”和“ callCount”列的表。我的目标是“左加入”和“分组依据”,但是我一直想念没有打过电话的员工。我怎样才能只保留名称并在其中放置零? 也许我很亲密,有人可以指出我的错字吗?在此先感谢您的帮助,以下是SQL: 问题答案: 这是一个JOIN而非NULL问题:您的过

  • 问题内容: 我有三个表: 命令 OrderId,int PK CustomerId,与客户之间为int FK,允许为NULL 顾客 CustomerId,int PK CompanyId,将FK转换为Company,不允许为NULL 公司介绍 CompanyId,int PK 名称nvarchar(50) 我想选择所有订单,无论是否有客户,如果有客户,也要选择客户的公司名称。 如果我使用此查询…

  • 问题内容: 我的查询有问题,该查询显示商店列表以及与之关联的产品数量。我已经玩了很长时间的左联接等,但无济于事。这些表具有以下结构: 商店含有表列:, 产品含表列:,,, 查询如下: 我没有去买有0件商品的商店。请问我该如何实现? 基础数据库是MySQL。 谢谢!马耳他 问题答案: 您需要在左侧购物,因为右侧可能没有数据,在本例中为PRODUCT。 不仅如此,您还需要WHERE条件作为LEFT-J