【问题标题】:How to get a summary table like this? A pivot table?如何获得这样的汇总表?数据透视表?
【发布时间】:2014-06-03 16:18:23
【问题描述】:

我正在将 T-SQL 与 MS SQL Server 一起使用。

我有一张这样的桌子:

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脚本来完成吗?

更理想的是,我希望我可以指定开始/结束/步长值。 :)

【问题讨论】:

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


【解决方案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

【讨论】:

  • 谢谢。是否可以不对开始/结束/步骤值进行硬编码?在数据透视部分,是否可以不列出所有唯一值,因为这取决于开始/结束/步骤值。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2021-12-11
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2023-04-04
    • 2018-02-14
    • 2022-11-28
    • 2014-11-03
    • 1970-01-01
    相关资源
    最近更新 更多