SQL使用数据透视后添加多个计算的行

时间:2018-06-27 13:13:33

标签: sql sql-server pivot grouping

我有一个看起来像这样的数据表:

|Agency|Rating     |AVG|
------------------------
|Army  |Exceptional|10 |
|Navy  |Very Good  |8.5|

我需要确定/计算每种类型的评级的数量,并计算每种评级类别的总数和百分比,因此看起来像这样:

|Rating        |Army|Navy|
--------------------------
|Exceptional   |1   |0   |
|Very Good     |0   |1   |
|Satisfactory  |0   |0   |
|Marginal      |0   |0   |
|Unsatisfactory|0   |0   |
|Total         |1   |1   |
|% of Ex       |100 |0   |
|% of VG       |0   |100 |
|% of Sat      |0   |0   |
|% of Mar      |0   |0   |
|% of Uns      |0   |0   |

使用以下查询:

select RatingWords as Rating, case when grouping([RatingWords]) = 1 then 
'Total' else [RatingWords] end as [RatingWords], Sum([Navy]) as Navy, 
sum([Army]) as Army
from
(select ratingwords, agency,
CASE WHEN Average BETWEEN 8.6 AND 10 THEN 1 else 0 end as Exceptional,
case WHEN Average BETWEEN 7.1 AND 8.5 THEN 1 else 0 end as VeryGood,
case WHEN Average BETWEEN 3.1 AND 7.0 THEN 1  else 0 end as Satisfactory,
case WHEN Average BETWEEN 0.1 AND 3.0 THEN 1 else 0 end as Marginal,
case WHEN Average = 0 THEN 1 ELSE 0 END as Unsatisfactory
from dbo.DOD_Average) as sourcetable
pivot
(
Count(exceptional)
for Agency in ([Navy], [Army])
) as PivotTable
group by grouping sets ((RatingWords),())

我得到下表:

|Rating        |Army|Navy|
--------------------------
|Exceptional   |1   |0   |
|Very Good     |0   |1   |
|Satisfactory  |0   |0   |
|Marginal      |0   |0   |
|Unsatisfactory|0   |0   |
|Total         |1   |1   |

所以我的问题是,如何在“总计”行下添加另一个组以计算百分比?或者,如果这不是创建此报告的最佳方法,我愿意对其进行重新加工。

2 个答案:

答案 0 :(得分:0)

使用现有查询作为CTE,您可以从中进行SELECT *,然后通过一系列UNION ALL查询来获取所需的每个百分比行。

答案 1 :(得分:0)

将以上查询保留在表变量中,并UNION ALL保留百分比查询。像这样:

Declare @table table (Rating nvarchar(60), Army int, Navy int);
Insert into @table 
select RatingWords as Rating, case when grouping([RatingWords]) = 1 then 
'Total' else [RatingWords] end as [RatingWords], Sum([Navy]) as Navy, 
sum([Army]) as Army
from
(select ratingwords, agency,
CASE WHEN Average BETWEEN 8.6 AND 10 THEN 1 else 0 end as Exceptional,
case WHEN Average BETWEEN 7.1 AND 8.5 THEN 1 else 0 end as VeryGood,
case WHEN Average BETWEEN 3.1 AND 7.0 THEN 1  else 0 end as Satisfactory,
case WHEN Average BETWEEN 0.1 AND 3.0 THEN 1 else 0 end as Marginal,
case WHEN Average = 0 THEN 1 ELSE 0 END as Unsatisfactory
from dbo.DOD_Average) as sourcetable
pivot
(
Count(exceptional)
for Agency in ([Navy], [Army])
) as PivotTable
group by grouping sets ((RatingWords),())

Declare @army int, @navy int;
Select @army = Army, @navy = Navy from @table where Rating = 'Total';

Select * from @table
union all
Select '% of'+Rating, (Army/@army)*100, (Navy/@navy)*100 from @table 
where Rating <> 'Total'