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

Posted

技术标签:

【中文标题】如何根据 SQL 中的分区对行求和?【英文标题】:How to sum rows according to partition in SQL? 【发布时间】:2014-05-29 05:35:11 【问题描述】:

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

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

列名: 溢价、佣金、净溢价

    col1    col2   col3

数据

    124    213    producer
     -1     12    producer

数据2

    -1    312    producer
    444    -555  producer
    100    555   producer

    col1    col2   col3

数据

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

数据2

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

【问题讨论】:

你能发布一个预期结果的样本吗? 它在 excel 中。先生,我怎么发给你? 参考这个***.com/questions/23904192/… 并添加这样的输出。我的意思是你可以输入一个样本 @Nithesh:看看:D 希望cha给你正确的答案。试试这样 【参考方案1】:

使用 ROLLUP:

这是一个包含几列的集合(仅限高级版)

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 Fiddle 中不起作用):

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

【讨论】:

sqlfiddle.com/#!3/4e3e80/29 看看我的查询.. 你怎么能结合两个选择语句?谢谢 我认为rollup 组的最后一行将是您的结果 顺便说一句,最后一行是你的Grand Total 如何删除最后一行? :D 我不能在 SELECT 语句中添加这个列怎么样? (EndorsementId, PolicyNumber,InsuredName, EffectiveDate, ExpirationDate, EndorsementNumber,EffectFromDate,DueDate, Producer, 是的,你可以!我已经更新了答案并包含了一个不使用 ROLLUP 的解决方案【参考方案2】:

另一种方法是 UNION 将总行数添加到原始数据并以所需的方式对结果进行排序,直接与来自 fiddle 的数据链接是

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)

【讨论】:

以上是关于如何根据 SQL 中的分区对行求和?的主要内容,如果未能解决你的问题,请参考以下文章

Handsontable:如何对行求和?

如何在 MySQL 中对行进行求和

在R中按月对行求和

SQL |如何对 3 个项目的分区组求和?

mysql 行转列,对列的分组求和,对行求和

tensor求和( tensor.sum())