取消透视范围以生成类似报告的结果

时间:2016-08-19 11:42:45

标签: sql sql-server

我在创建一个使用一些二进制文件或范围的SQL查询时遇到了问题。

我有一张桌子,看起来像这样:

Id  Value  Range
1   101    >100
2   8      >5
3   330    >100
4   230    >100
5   8      >5
6   101    >100
7   8      >5
8   330    >100
9   230    >100
10  8      >5

然后我可以用一个计数进行聚合查询,按照Range进行分组,得到类似的东西(这些点不会弄乱格式):

Range  Total 
.>100  6 
.>5    4 

但是,我想要的就是报告,如下所示:

Range  N1   P1     N2   P2  
Total  10   100%    
.>5    4    40%    6    60% 
.>100  6    60%    4    40% 

我所做的就是删除组并执行一个outter选择,以我想要的方式对这些列进行求和,并将它们分开,但我只是通过使用range和N1列来实现这一点,所以它看起来像这样:

Range  N1     
Total  10     
.>5    4    
.>100  6 

我使用的查询(在univoting之前)是:

select [.>5] = sum(case when ([Range] > '>5' then 1 else 0 end)
[.>100] = sum(case when ([Range] > '>100' then 1 else 0 end)
[Total] = count(*)
From tableName

如何让我的结果看起来像这样:

Range  N1   P1     N2   P2  
Total  10   100%    
.>5    4    40%    6    60% 
.>100  6    60%    4    40% 

注意:我不一定要解开,这只是我发现如何去做的一种方式,我可能有更好的方式。

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

您的结果似乎非常多余。忽略“总计”行,您似乎想要这些结果:

select Range, count(*) as n1,
       count(*) * 1.0 / sum(count(*)) over () as p1,
       sum(count(*)) over () - count(*) as n2,
       1 - count(*) * 1.0 / sum(count(*)) over () as p2
From tableName
group by [Range];

您可以使用grouping sets添加总计:

select Range, count(*) as n1,
       count(*) * 1.0 / sum(count(*)) over () as p1,
       sum(count(*)) over () - count(*) as n2,
       1 - count(*) * 1.0 / sum(count(*)) over () as p2
From tableName
group by grouping sets ((), ([Range]));

答案 1 :(得分:0)

你好Angra可能是这段代码帮助你,我检查你的场景它返回你期望的结果。

选择[范围] ='> 5',N1 =总和(情况时([范围] ='> 5')然后1其他0结束),P1 = concat(sum(([范围] ='> 5')然后1其他0结束的情况),' 0%') ,N2 = sum(([Range] ='> 100')然后1 else 0 end),P2 = concat(sum(([Range] ='> 100& #39;)然后1其他0结束),' 0%')来自tableName

联合

选择[范围] ='> 100',N1 = sum(情况时([范围] ='> 100')然后1其他0结束),P1 = concat(sum(([范围] ='> 100')然后1其他0结束的情况),' 0%') ,N2 = sum(([Range] ='> 5')然后1 else 0 end),P2 = concat(sum(([Range] ='> 5& #39;)然后1其他0结束),' 0%')来自tableName

联盟

从tableName中选择[Range] =' Total',N1 = count(value),P1 = concat(count(value),' 0%'),null,null

答案 2 :(得分:0)

declare @t table (Id int, Value int,  Range varchar(5))
insert into @t values
(1,   101,   '>100' ),
(2,   8  ,    '>5' ),
(3,   330,    '>100'),
(4,   230,    '>100'),
(5,   8  ,    '>5'),
(6,   101,    '>100'),
(7,   8  ,    '>5'),
(8,   330,    '>100'),
(9,   230,    '>100'),
(10,  8  ,    '>5')

select  CASE
        WHEN T.RANGE = '>0' THEN 'Total'
        else t.range
        end as Range,
        t.n1,t.p1,
        isnull(cast(t.n2 as varchar(6)),'') n2,
        ISNULL(cast(t.p2 as varchar(6)),'') p2
from
(
select  s.range,
        s.n1, 
        cast(cast(s.n1 as decimal(10,2))  / (select count(*) from @t) *100 as decimal(10,2)) p1,
        case 
            when s.range <> '>0' then (select count(*) from @t where range <> s.range)
        end as n2,
        case 
            when s.range <> '>0' then 
                cast(
                cast((select count(*) from @t where range <> s.range) as decimal(10,2)) /
                cast((select count(*) from @t) as decimal(10,2)) *100.00
                as decimal(10,2))
        end as p2
from
(
select t.range,count(*) n1
from    @t t
group   by range 
union  
select  '>0',count(*)
from    @t
) s
) t
order by cast(replace(range,'>','') as int)

结果

Range n1          p1                                      n2     p2
----- ----------- --------------------------------------- ------ ------
Total 10          100.00                                         
>5    4           40.00                                   6      60.00
>100  6           60.00                                   4      40.00