【问题标题】:How to sum column wise and row-wise in SQL Server?如何在 SQL Server 中按列和按行求和?
【发布时间】:2017-12-21 06:05:56
【问题描述】:

请看下面

我要找的是

总计应该同时发生在行和列级别

我的尝试

declare @t table(aggrementid varchar(20), bom_pos int, bucket int null, paymentstatus varchar(50))

insert into @t 
    select '1', 3000, null, null  
    union all 
    select '2', 3000, 0, 'Non-Delinquient' 
    union all
    select '3', 4000, 0, 'Non-Delinquient' 
    union all 
    select '4', 5000, 0, 'Non-Delinquient' 
    union all 
    select '5', 7000, 0, 'NPA' 
    union all 
    select '6', 8000, 1, 'NPA'

Select 
    bucket,
    [Non-Delinquient], [NPA], [RollBack], [RollForward],
    [Stabilized], [Normalized], [PaymentStatusY],
    Total = iif([Non-Delinquient] is null, 0, [Non-Delinquient]) + 
        iif([NPA] is null, 0, [NPA]) + 
        iif([RollBack] is null, 0, [RollBack]) + 
        iif([RollForward] is null, 0, [RollForward]) + 
        iif([Stabilized] is null, 0, [Stabilized]) + 
        iif([Normalized] is null, 0, [Normalized]) + 
        iif([PaymentStatusY] is null, 0, [PaymentStatusY])
From
    (Select 
         --aggrementid, 
         bom_pos,
         bucket, paymentstatus      
     From 
         @t) as PivotSource
PIVOT
    (sum(bom_pos) FOR paymentstatus IN ([Non-Delinquient], [NPA],[RollBack],[RollForward],[Stabilized],[Normalized],[PaymentStatusY])
    ) as Pvt
Where 
    bucket is not null

这会返回这个结果:

另外,也可以通过 Rollup 函数等来实现吗?

【问题讨论】:

    标签: tsql sql-server-2014


    【解决方案1】:

    我认为您可以将GROUP BYGROUPING SETS 一起使用

    declare @t table(aggrementid varchar(20), bom_pos int, bucket int null, paymentstatus varchar(50))
    
    insert into @t 
        select '1', 3000, null, null  
        union all 
        select '2', 3000, 0, 'Non-Delinquient' 
        union all
        select '3', 4000, 0, 'Non-Delinquient' 
        union all 
        select '4', 5000, 0, 'Non-Delinquient' 
        union all 
        select '5', 7000, 0, 'NPA' 
        union all 
        select '6', 8000, 1, 'NPA'
    
    Select 
        isnull(CAST(bucket AS varchar(10)),'Total') bucket,
        SUM([Non-Delinquient]) [Non-Delinquient],
        SUM([NPA]) [NPA],
        SUM([RollBack]) [RollBack],
        SUM([RollForward]) [RollForward],
        SUM([Stabilized]) [Stabilized],
        SUM([Normalized]) [Normalized],
        SUM([PaymentStatusY]) [PaymentStatusY],
        SUM(isnull([Non-Delinquient],0) + isnull([NPA],0) + isnull([RollBack],0) + isnull([RollForward],0) + isnull([Stabilized],0) + isnull([Normalized],0) + isnull([PaymentStatusY],0)) Total
    From
        (Select 
             --aggrementid, 
             bom_pos,
             bucket, paymentstatus      
         From 
             @t) as PivotSource
    PIVOT
        (sum(bom_pos) FOR paymentstatus IN ([Non-Delinquient], [NPA],[RollBack],[RollForward],[Stabilized],[Normalized],[PaymentStatusY])
        ) as Pvt
    Where 
        bucket is not null
    GROUP BY GROUPING SETS(
                            (bucket),
                            ()
                          )
    

    请参阅以下示例以了解其工作原理

    SELECT
      CASE GROUPING_ID(GroupID,SubgroupID)
        WHEN 3 THEN 'Total'
        WHEN 1 THEN 'Subtotal by Group'
        WHEN 0 THEN ''
      END RowTitle,
    
      GroupID,
      SubgroupID,
      SUM(Value) Value
    FROM
      (
        SELECT 1 GroupID,1 SubgroupID,10 Value
        UNION ALL SELECT 1 GroupID,2 SubgroupID,5 Value
        UNION ALL SELECT 1 GroupID,3 SubgroupID,5 Value
        UNION ALL SELECT 2 GroupID,1 SubgroupID,11 Value
        UNION ALL SELECT 2 GroupID,2 SubgroupID,12 Value
      ) q
    GROUP BY GROUPING SETS(
                (GroupID,SubgroupID),
                (GroupID),
                ()
              )
    

    您也可以将SUMCASE 一起使用,而不是PIVOT。对我来说更清楚

    SELECT
      bucket,
      SUM(CASE WHEN paymentstatus='Non-Delinquient' THEN bom_pos END) [Non-Delinquient],
      SUM(CASE WHEN paymentstatus='NPA' THEN bom_pos END) [NPA],
      SUM(CASE WHEN paymentstatus='RollBack' THEN bom_pos END) [RollBack],
      SUM(CASE WHEN paymentstatus='RollForward' THEN bom_pos END) [RollForward],
      SUM(CASE WHEN paymentstatus='Stabilized' THEN bom_pos END) [Stabilized],
      SUM(CASE WHEN paymentstatus='Normalized' THEN bom_pos END) [Normalized],
      SUM(CASE WHEN paymentstatus='PaymentStatusY' THEN bom_pos END) [PaymentStatusY],
      SUM(bom_pos) Total
    FROM @t
    WHERE paymentstatus IN('Non-Delinquient', 'NPA','RollBack','RollForward','Stabilized','Normalized','PaymentStatusY')
    GROUP BY GROUPING SETS(
                            (bucket),
                            ()
                          )
    

    【讨论】:

      【解决方案2】:
      declare @t table(aggrementid varchar(20), bom_pos int, bucket nvarchar(max) null, paymentstatus varchar(50))
      
      insert into @t 
          select '1', 3000, null, null  
          union all 
          select '2', 3000, 0, 'Non-Delinquient' 
          union all
          select '3', 4000, 0, 'Non-Delinquient' 
          union all 
          select '4', 5000, 0, 'Non-Delinquient' 
          union all 
          select '5', 7000, 0, 'NPA' 
          union all 
          select '6', 8000, 1, 'NPA'
      
      
      
      Select 
         bucket,
          [Non-Delinquient], [NPA], [RollBack], [RollForward],
          [Stabilized], [Normalized], [PaymentStatusY],
          Total = isnull([Non-Delinquient],0) + 
                  isnull([NPA],0) + 
                  isnull([RollBack],0) + 
                  isnull([RollForward],0) + 
                  isnull([Stabilized],0) + 
                  isnull([Normalized],0) + 
                  isnull([PaymentStatusY],0) 
      From
          (Select 
               --aggrementid, 
               bom_pos,
               bucket, paymentstatus      
           From 
               @t) as PivotSource
      PIVOT
          (sum(bom_pos) FOR paymentstatus IN ([Non-Delinquient], [NPA],[RollBack],[RollForward],[Stabilized],[Normalized],[PaymentStatusY])
          ) as Pvt
      Where 
          bucket is not null
      
          union all
      
          Select 
          'Total',
          sum([Non-Delinquient]), sum([NPA]), sum([RollBack]), sum([RollForward]),
          sum([Stabilized]), sum([Normalized]), sum([PaymentStatusY]),
          Total = (isnull(sum([Non-Delinquient]),0) + 
                  isnull(sum([NPA]),0) + 
                  isnull(sum([RollBack]),0) + 
                  isnull(sum([RollForward]),0) + 
                  isnull(sum([Stabilized]),0) + 
                  isnull(sum([Normalized]),0) + 
                  isnull(sum([PaymentStatusY]),0)) 
      From
          (Select 
               --aggrementid, 
               bom_pos,
               bucket, paymentstatus      
           From 
               @t) as PivotSource
      PIVOT
          (sum(bom_pos) FOR paymentstatus IN ([Non-Delinquient], [NPA],[RollBack],[RollForward],[Stabilized],[Normalized],[PaymentStatusY])
          ) as Pvt
      Where 
          bucket is not null
      

      【讨论】:

        猜你喜欢
        • 2016-06-07
        • 1970-01-01
        • 2017-06-15
        • 1970-01-01
        • 1970-01-01
        • 2015-08-20
        • 1970-01-01
        • 2021-10-20
        • 2020-09-14
        相关资源
        最近更新 更多