SQLServer 行转列,统计,二次分组
create table test
(
bizdate datetime, --日期
classes varchar(50), --班次 '白班' 或 '夜班'
qty int --产量
)
insert into test
select '2011-04-01','白班',154 union
select '2011-04-01','白班',400 union
select '2011-04-02','夜班',40 union
select '2011-04-02','白班',150 union
select '2011-04-03','夜班',130 union
select '2011-04-03','白班',400 union
select '2011-04-04','白班',520 union
select '2011-04-04','白班',1000 union
select '2011-04-04','白班',240
ps.日产量指每天的产量,包括白班和晚班
要统计成如下格式(日期唯一):
日期 白班总产量 夜班总产量 日产量
之前的写法是:
select bizdate,
Case when classes='白班' then Sum(qty) else 0 end AS '白班产量',
Case when classes='夜班' then SUM(qty) else 0 end AS '夜班产量'
from #test
group by bizdate,classes
此方式得到的结果中,每行只有一个班次有值,同一日期同一班次的产量没有合计起来
以下是正确结果,与上面不同的是,sum()函数用在了最外边,并且group by 里去掉了classes(此处影响很大)
select bizdate,
Sum(Case when classes='白班' then qty else 0 end) AS '白班产量',
Sum(Case when classes='夜班' then qty else 0 end) AS '夜班产量',
Sum(qty ) AS '日产量'
from test Group by bizdate
说明:
第一种写法之所以无法合计是因为在group by后多写了classes这列,sqlserver会依次按照bizDate、classes去分组,结果就导致班次有重复的。
第二种写法首先去掉多余的classes列(此列是需要被合并的,写在group by后纯属多余还大大影响查询结果),但是运行时会报错说classes未包含在聚合函数里,此时只需要把SUM()函数移到case when 外面,即可。这样就不必把classes写在group by里而去影响查询结果了。