将聚合记录集逆时针和顺时针旋转90度
在输出统计结果时可能需要将列变成行,而将聚合结果(如count、sum)作为记录的第一行,先看如下的SQL语句:
declare?
@t?
table
(name?
varchar
(
20
))
insert? @t select? ' abc '? union? all select? ' xxx '? union? all select? ' xxx '? union? all select? ' ttt ' select? *? from? @t ??? 在执行上面的SQL语句后,会输出如图1所示的记录集。
图1
??? 上图显示的是一个普通的记录集,如果要统计name字段的每个值的重复数,需要进行分组,如下面的SQL如示:
select?
count
(name)?
as
?c?,name??
from?
@t?
group?
by
?name?
图2
??? 如果我们有一个需求,需要如图3所示的聚合结果。
图3
????? 从图3可以看出,查询结果正好是图2的结果逆时针旋转90度,也就是说,name列的值变成了列名,而c列的值变成了第一行的记录。图2所示的c和name字段消失了。 ??? 当然,要达到这个结果并不困难,看如下的SQL语句:
select
?(
select?
count
(name)?
from?
@t?
where
?name
=
'
abc
'
)?
as
?abc,?
???????( select? count (name)? from? @t? where ?name = ' ttt ' )? as ?xxx, ???????( select? count (name)? from? @t? where ?name = ' xxx ' )? as ?ttt
select?
*?
from?
@t
?pivot(
count
(name)?
for
?name?
in
(
[
abc
]
?,
[
ttt
]
,
[
xxx
]
))
1.?pivot函数需要指定聚合函数,如count、sum等,for关键字和聚合函数都要使用需要聚合的字段名,在本例中是name。 2.?in关键字负责指定每组需要聚合的值,用[...]将这些值括起来。实际上,这些值也相当于我们第一种聚合方法中的where条件,例如,where name='abc'、where name='ttt',当然,这些值也是输出记录集的列名。 3.?在最后要为pivot函数起一个别名。
declare?
@t?
table
(name?
varchar
(
20
))
insert? @t select? ' abc '? union? all select? ' xxx '? union? all select? ' xxx '? union? all select? ' ttt ' ; with ?tt? as ( select? *? from? @t ?pivot( count (name)? for ?name? in ( [ abc ] ?, [ xxx ] ))?p) select? *? from ?tt ??? 上面的SQL语句将输出如图3所示的结果。如果将最后一条SQL语句(select * from tt)换成如下的SQL语句,将输出如图2所示的结果。
select?
*?
from
?tt??unpivot(
[
c
]?
for
?name?
in
(
[
abc
]
?,
[
xxx
]
,
[
ttt
]
))?p
??? 要注意的是,[c]中的c表示聚合结果列的字段名,name表示要聚合列的字段名,这两个值可以是任意满足字段名命名规则的字符串,?[abc],[xxx],[ttt]分别是图3所示的记录集的字段名,这些值必须一致。执行下面的SQL语句将获得图4的输出结果。
select?
*?
from
?tt??unpivot(
[
统计值
]?
for
?统计名?
in
(
[
abc
]
?,
[
ttt
]
))?p
图4
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |