如何获得这样的汇总表?数据透视表?

时间:2014-04-19 05:30:10

标签: sql sql-server tsql pivot pivot-table

我正在使用带有MS SQL Server的T-SQL。

我有一张这样的表:

Category         Value
A                 150
B                 200
C                 300
A                 120
A                 300
C                 500
D                 200
...

我想得到一个这样的汇总表:

DistinctCategory     Value>100    Value>200    Value>300 ...(column value step is 100)
A                      3              1            0
B                      1              0            0
C                      2              2            1
D                      1              0            0
...

我想SQL数据透视表可以做到这一点,但是如何实现呢?

理想情况下,我希望摘要表可以自适应原始表中的值范围,并使每个列的值步长为100。可以用T-SQL脚本完成吗?

理想情况下,我希望我可以指定开始/结束/步骤值。 :)

2 个答案:

答案 0 :(得分:1)

您可以这样做:

with
tab1 as (select 100 as v1,(select max(value) from table1) v2,table1.* from table1),
tab2(v1,v2,category,value) as
(select v1,v2,category,value from tab1 
where value > v1
union all
select v1 + 100 as v1,v2,category,value from tab2 
where value > v1 + 100 and v2 >= v1),
tab3 as (select v1,category,count(*) cnt from tab2
group by v1,category)
select * from
(select * from tab3) as sour
PIVOT
(
    MAX([cnt])
    FOR [v1] IN ([100],[200],[300],[400])
) as pvt;

或者这个:

with
tab1 as (select 100 as v1,(select max(value) from table1) v2,table1.* from table1),
tab2(v1,v2,category,value) as
(select v1,v2,category,value from tab1 
where value > v1
union all
select v1 + 100 as v1,v2,category,value from tab2 
where value > v1 + 100 and v2 >= v1),
tab3 as (select v1,category,count(*) cnt from tab2
group by v1,category)
select category,
MAX(CASE WHEN v1 = 100 THEN cnt ELSE NULL END) [value > 100],
MAX(CASE WHEN v1 = 200 THEN cnt ELSE NULL END) [value > 200],
MAX(CASE WHEN v1 = 300 THEN cnt ELSE NULL END) [value > 300],
MAX(CASE WHEN v1 = 400 THEN cnt ELSE NULL END) [value > 400]
from tab3 group by category;

SQL Fiddle

答案 1 :(得分:0)

如果你想动态地做所有事情,你可以做这样的查询:

DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

with
tab1 as (select 100 as v1,(select max(value) from table1) v2,table1.* from table1),
tab2(v1,v2,category,value) as
(select v1,v2,category,value from tab1 
where value > v1
union all
select v1 + 100 as v1,v2,category,value from tab2 
where value > v1 + 100 and v2 >= v1),
tab3 as (select v1,category,count(*) cnt from tab2
group by v1,category)--,
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.v1) 
        FROM tab3 c
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @query =
'with
tab1 as (select 100 as v1,(select max(value) from table1) v2,table1.* from table1),
tab2(v1,v2,category,value) as
(select v1,v2,category,value from tab1 
where value > v1
union all
select v1 + 100 as v1,v2,category,value from tab2 
where value > v1 + 100 and v2 >= v1),
tab3 as (select v1,category,count(*) cnt from tab2
group by v1,category)
select * from
(select * from tab3) as sour
PIVOT
(
    MAX([cnt])
    FOR [v1] IN ('+ @cols +')
) as pvt'

execute(@query);

SQL Fiddle