如何在SQL Server中按列顺序和行方式求和?

时间:2017-12-21 06:05:56

标签: tsql sql-server-2014

请看下面的

enter image description here

我正在寻找的是

enter image description here

总计应该在行和列级别

我的尝试

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

返回此结果:

enter image description here

另外,使用Rollup功能等可以实现同样的效果吗?

2 个答案:

答案 0 :(得分: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),
            ()
          )

enter image description here

您也可以SUM使用CASE代替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),
                        ()
                      )

答案 1 :(得分:1)

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