使用Case进行子组聚合

时间:2012-12-05 23:28:20

标签: sql sql-server-2008 tsql

我正在尝试返回groupid,masteraccountnames和CashAmountDiff的列表,其中任何日期的同一groupid交易的CashAmount总和大于100。

表模式如下:

TradeT1

TradeId | SubAccountId | MasterAccId | GroupId | TradeDate | TradeType 

MasterAccount

Id | MasterAccName 

SubAccount

Id | SubAccName | MasterAccountId 

每个SubAccount都链接到MasterAccount。这是一种多对一的关系。

TradeType决定交易的“方向”,无论是借方还是贷方。我无法为每个groupid添加借记和点数。我的问题只是总结一切。我不确定如何结合信用时的情况(乘以CashAmount * -1),当借方只使用CashAmount时的情况

一个groupid总会有超过1个tradeid。

我在这里使用SQL表格和我的努力:http://www.sqlfiddle.com/#!3/45580/1/0

SELECT 
t.groupId,
ma.MasterAccName,
sum(CASE WHEN t.tradetype = 'Credit' 
       THEN sum(-1*t.cashamount)
    ELSE sum(t.cashamount)) 
END as CashDiff 
FROM tradet1 t
JOIN masteraccount ma
ON t.masteraccid = ma.id 
WHERE t.groupid > -1
GROUP BY t.groupid, ma.MasterAccName
HAVING count(t.groupid) > 1 and sum(t.cashamount) > 100

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:1)

这只是适合+/-的查询。我可能有退路的迹象。

Select 
  t.groupId,
  ma.MasterAccName,
  Sum (Case When TradeType = 'Credit' Then -t.cashamount Else t.cashamount End) AS 'CashDiff'
From 
  tradet1 t
      Inner Join
  masteraccount ma
      On t.masteraccid = ma.id 
 Where
  t.groupid > -1
 Group By
  t.groupid,
  ma.MasterAccName
Having
  Count(t.groupid) > 1 And
  Sum (Case When TradeType = 'Credit' Then -t.cashamount Else t.cashamount End) > 100

http://www.sqlfiddle.com/#!3/45580/20

答案 1 :(得分:1)

您可以通过转换子查询中的信用和借记并在汇总查询中使用这些结果来简化此查询。

SELECT    [tt].[GroupId] ,
          [ma].[MasterAccName] ,
          CASE WHEN [tt].[TradeType] = 'Credit'
               THEN [tt].[CashAmount] * -1
               ELSE [tt].[CashAmount]
               END AS CashAmount
FROM      [dbo].[TradeT1] AS tt
          JOIN [dbo].[MasterAccount] AS ma ON [tt].[MasterAccId] = [ma].[Id]

有了这个,你就可以在周围的聚合查询中使用好的CashAmounts列表作为正面和负面。

整个查询看起来像这样

SELECT  [tn].[GroupId] ,
        [tn].[MasterAccName] ,
        SUM([tn].[CashAmount]) AS CashDiff
FROM    ( SELECT    [tt].[GroupId] ,
                    [ma].[MasterAccName] ,
                    CASE WHEN [tt].[TradeType] = 'Credit'
                         THEN [tt].[CashAmount] * -1
                         ELSE [tt].[CashAmount]
                    END AS CashAmount
          FROM      [dbo].[TradeT1] AS tt
                    JOIN [dbo].[MasterAccount] AS ma ON [tt].[MasterAccId] = [ma].[Id]
        ) AS tn
GROUP BY [tn].[GroupId] ,
        [tn].[MasterAccName]
HAVING  ABS(SUM([tn].[CashAmount])) > 100 AND COUNT([tn].[GroupId]) > 1