SQL根据不同的记录类型进行分组和聚合

时间:2013-07-10 01:06:38

标签: sql sql-server tsql stored-procedures

考虑下面的表结构

ADateTime    AGroupName   ARecordType   AValue
==========   ==========   ===========   ======
2013-01-01   Ninjas       A             10
2013-01-01   Ninjas       B             5
2013-01-01   Ninjas       C             2
2013-01-01   Ninjas       D             1
2013-01-01   Ninjas       E             0
2013-01-01   Clowns       A             8
2013-01-01   Clowns       B             4
2013-01-01   Clowns       E             1
2013-01-08   Ninjas       A             7
2013-01-08   Ninjas       B             3
2013-01-08   Ninjas       E             1
2013-01-08   Clowns       A             4
2013-01-08   Clowns       B             3

我需要为ADateTime和AGroupName的每个组合计算2个值(CalcVal1和CalcVal2)。换句话说,我需要GROUP BY ADateTime和AGroupName(这是最简单的部分)。

注意:正如您从示例数据中看到的那样,无法保证给定分组存在某种记录类型...所以外部联接并在必要时合并!

我想弄清楚的是如何根据ARecordType的值计算CalcVal1和CalcVal2。以下是CalcVal1和CalcVal2的规格......

  1. CalcVal1是(AValue的和,其中ARecordType ='A')
  2. CalcVal2是(AValue的SUM,其中ARecordType IN('B','C'))MINUS (AValue的和,其中ARecordType IN('D','E'))
  3. 我期望的结果集是

    ADateTime    AGroupName   CalcVal1   CalcVal2
    ==========   ==========   ========   ========
    2013-01-01   Ninjas       10            6
    2013-01-01   Clowns       8             3
    2013-01-08   Ninjas       7             2
    2013-01-08   Clowns       4             3
    

    我在SQL-Server 2005上使用T-SQL。欢迎使用SQL或存储过程。 TIA,我已经太老了,现在是他们让我成为CTO的时候了! (;-D)

1 个答案:

答案 0 :(得分:4)

您可以使用条件聚合执行此操作,几乎就像您描述的那样:

select ADateTime, AGroupName,
       SUM(case when ARecordType = 'A' then AValue else 0 end) as CalcVal1,
       (SUM(case when ARecordType in ('B', 'C') then AValue else 0 end) -
        SUM(case when ARecordType in ('D', 'E') then AValue else 0 end)
       ) as CalcVal2
from t
group by ADateTime, AGroupName