如何根据SQL中的分区对行进行求和?

时间:2014-05-29 05:35:11

标签: sql sql-server-2008 sum window-functions

如何根据它的分区在行中添加值,并且总和将放在每个分区下面(每个分区下面的新行/ s将是总和的容器)?

使用以下链接: http://sqlfiddle.com/#!3/4e3e80/4

列名: Premium,Commission,NetPremium

    col1    col2   col3

数据

    124    213    producer
     -1     12    producer

data2

    -1    312    producer
    444    -555  producer
    100    555   producer

    col1    col2   col3

数据

    124    213    producer
     -1     12
    123    225    null     <<<<'result'

data2

    -1    312    producer
    444    -555  
    100    555
    543    312   null      <<<<'result'

2 个答案:

答案 0 :(得分:1)

使用ROLLUP:

这是一个包含几列(仅限Premium)的集合

SELECT 
    (CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
    rno,
    sum(PREMIUM)
FROM
(                   
    SELECT 
        ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
        *
    FROM [endorsement]
) As temp1
GROUP by EndorsementId, rno
with rollup

结果:

|  COL1 |    RNO | COLUMN_2 |
|-------|--------|----------|
| 13519 |      1 |      750 |
|       |      2 |        0 |
|       |      3 |        0 |
|       | (null) |      750 |
| 13524 |      1 |      157 |
|       |      2 |        0 |
|       |      3 |      158 |
|       |      4 |       16 |
|       | (null) |      331 |
. . . . . . . 

SQL Fiddle

顺便说一句,使用Compute BY可以实现相同的结果(它在SQL小提琴中不起作用):

SELECT 
    (CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
    rno,
    PREMIUM
FROM
(                   
    SELECT 
        ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
        *
    FROM [endorsement]
) As temp1
ORDER by EndorsementId, rno
COMPUTE SUM(Premium) BY EndorsementId

如果您忽略ROLLUP生成的最后一行有太多麻烦,那么您可以使用以下语句,该语句将使用组总计生成所需的结果。这有点长,但工作做得好。 SQL Fiddle

SELECT 
    (CASE rno WHEN 1 THEN EndorsementId  WHEN 9999999999 THEN 'Total'ELSE '' END )AS [Endorsement ID],
     (CASE rno WHEN 1 THEN PolicyNumber  ELSE ''  END )AS [Policy Number],
      (CASE rno WHEN 1 THEN InsuredName  ELSE ''  END )AS [Insured Name],
       (CASE rno WHEN 1 THEN [temp1].[EffectiveDate]  ELSE ''  END )AS [Effective Date], 
        (CASE rno WHEN 1 THEN [temp1].[ExpirationDate]  ELSE ''  END )AS [Expiration Date], 
         (CASE rno WHEN 1 THEN [temp1].[EndorsementNumber]  ELSE ''  END )AS [Endorsement Number],
          (CASE rno WHEN 1 THEN [temp1].[EffectFromDate]  ELSE ''  END )AS [EffectFrom Date],
           (CASE rno WHEN 1 THEN [temp1].[DueDate]  ELSE ''  END )AS [Due Date],
            (CASE rno WHEN 1 THEN [temp1].[Producer]  ELSE ''  END )AS [Producer],
             Premium,
              Commission,
               NetPremium AS [Net Premium]          
FROM
(                   
    SELECT 
        ROW_NUMBER() OVER(PARTITION BY EndorsementId ORDER BY PolicyNumber) AS rno,
        *
    FROM [endorsement]
UNION ALL
    SELECT
             9999999999 AS rno,
             EndorsementId, 
             '', 
             '', 
             '', 
             '', 
             '',
             '',
             '',
             '',
             SUM(Premium) AS Premium,
             SUM(Commission) AS Commission,
             SUM(NetPremium) AS NetPremium
    FROM [endorsement]
    GROUP BY EndorsementId
) As temp1
ORDER BY EndorsementId, rno

答案 1 :(得分:0)

另一种方法是UNION原始数据的总行数,并以所需的方式对结果进行排序,直接使用来自小提琴的数据

SELECT 
    (CASE rno WHEN 1 THEN EndorsementId ELSE '' END )AS col1,
    *
FROM
(                   
    SELECT 
        ROW_NUMBER() OVER(PARTITION BY EndorsementId 
                              ORDER BY PolicyNumber) AS rno,
        *
    FROM [endorsement]
    UNION ALL
    SELECT NULL As rno
         , EndorsementId, PolicyNumber, InsuredName, EffectiveDate
         , ExpirationDate, EndorsementNumber, EffectFromDate, DueDate, Producer
         , Sum(Premium) Premium
         , Sum(Commission) Commission
         , Sum(NetPremium) NetPremium
    From   [endorsement]
    Group By EndorsementId, PolicyNumber, InsuredName, EffectiveDate
           , ExpirationDate, EndorsementNumber, EffectFromDate, DueDate, Producer
) As temp1
Order By EndorsementId, Coalesce(rno, 999)