您可以为此使用 sql serverPIVOT
功能。如果您知道年份的所有值以及存储桶,则可以对查询进行硬编码:
select *
from
(
select
case
when times = 0 then '0'
when times >= 1 and times <=30 then '1-30'
when times >= 31 and times <=60 then '31-60'
when times >= 61 and times <=90 then '61-90'
when times >= 91 and times <=120 then '91-120'
else '121+' end bucket,
year
from yourtable
) src
pivot
(
count(year)
for year in ([2008], [2009], [2010], [2011], [2012])
) piv;
请参阅带有演示的 SQL Fiddle
如果您无权访问该PIVOT
函数,则可以将聚合函数与 a 一起使用CASE
:
select bucket,
sum(case when year = 2008 then 1 else 0 end) [2008],
sum(case when year = 2009 then 1 else 0 end) [2009],
sum(case when year = 2010 then 1 else 0 end) [2010],
sum(case when year = 2011 then 1 else 0 end) [2011],
sum(case when year = 2012 then 1 else 0 end) [2012]
from
(
select
case
when times = 0 then '0'
when times >= 1 and times <=30 then '1-30'
when times >= 31 and times <=60 then '31-60'
when times >= 61 and times <=90 then '61-90'
when times >= 91 and times <=120 then '91-120'
else '121+' end bucket,
year
from yourtable
) src
group by bucket
请参阅带有演示的 SQL Fiddle
如果您需要列出所有存储桶,那么您将希望将存储桶范围存储在表中或使用CTE
查询,那么您可以使用以下内容:
;with buckets(startbucket, endbucket, rnk) as
(
select 0, 0, 1
union all
select 1, 30, 2
union all
select 31, 60, 3
union all
select 61, 90, 4
union all
select 91, 120, 5
union all
select 121, null, 6
)
select
case when startbucket = 0 then '0'
when endbucket is null then cast(startbucket as varchar(50)) + '+'
else cast(startbucket as varchar(50)) + '-'+cast(endbucket as varchar(50)) end buckets,
[2008], [2009], [2010], [2011], [2012]
from
(
select rnk,
year,
startbucket,
endbucket
from buckets b
left join yourtable t
on t.times >= b.startbucket and t.times <= coalesce(b.endbucket, 100000)
) src
pivot
(
count(year)
for year in ([2008], [2009], [2010], [2011], [2012])
) piv;
请参阅带有演示的 SQL Fiddle
结果:
| BUCKETS | 2008 | 2009 | 2010 | 2011 | 2012 |
----------------------------------------------
| 0 | 0 | 0 | 0 | 0 | 0 |
| 1-30 | 1 | 1 | 2 | 1 | 0 |
| 31-60 | 0 | 1 | 0 | 0 | 0 |
| 61-90 | 1 | 0 | 0 | 0 | 1 |
| 91-120 | 0 | 0 | 0 | 0 | 0 |
| 121+ | 0 | 0 | 0 | 1 | 0 |
如果您需要转置已知数量的值(年),上述方法将非常有用。如果您有一个未知号码,那么您将需要实现动态 sql,类似于以下内容:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(year)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'with buckets(startbucket, endbucket, rnk) as
(
select 0, 0, 1
union all
select 1, 30, 2
union all
select 31, 60, 3
union all
select 61, 90, 4
union all
select 91, 120, 5
union all
select 121, null, 6
)
select
case when startbucket = 0 then ''0''
when endbucket is null then cast(startbucket as varchar(50)) + ''+''
else cast(startbucket as varchar(50)) + ''-''+cast(endbucket as varchar(50)) end buckets,
'+@cols+'
from
(
select rnk,
year,
startbucket, endbucket
from buckets b
left join yourtable t
on t.times >= b.startbucket and t.times <= coalesce(b.endbucket, 100000)
) src
pivot
(
count(year)
for year in ('+@cols+')
) piv;'
execute(@query)
请参阅带有演示的 SQL Fiddle
静态(硬编码)版本和动态版本的结果相同。