我正在使用带有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脚本完成吗?
理想情况下,我希望我可以指定开始/结束/步骤值。 :)
答案 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;
答案 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);