在MS-SQLServer 2005 中可以使用pivot運算符來來實現行列轉換. ,但在以下版本中必須使用 case when then else end 語句
下面以學生成績表來舉例:
id姓名 科目 成績
1 張三 語文 60
2 張三 數學 65
3 張三 外語 70
4 李四 語文 80
5 李四 數學 90
6 李四 外語 85
7 王五 語文 70
8 王五 數學 71
9 王五 外語 75
10 趙六 語文 64
11 趙六 數學 67
12 趙六 外語 76
查詢后得出:
姓名 語文數學外語
李四 80 90 85
王五 70 71 75
張三 60 65 70
趙六 64 67 76
准備數據:
select
*
from sysobjects
where
[
xtype
]
=
'
u
'
go
if exists( select id from sysobjects where name = ' studentscore ')
drop table studentscore -- 刪除與實驗沖突的表
go
create table studentscore -- 創建實驗表
(
[ id ] int identity( 1, 1),
[ name ] nvarchar( 20) not null,
subject nvarchar( 20) not null,
score int not null
)
go
select * from studentscore
go
-- 添加實驗數據
insert studentscore values ( ' 張三 ', ' 語文 ', ' 60 ');
insert studentscore values ( ' 張三 ', ' 數學 ', ' 65 ');
insert studentscore values ( ' 張三 ', ' 外語 ', ' 70 ');
insert studentscore values ( ' 李四 ', ' 語文 ', ' 80 ');
insert studentscore values ( ' 李四 ', ' 數學 ', ' 90 ');
insert studentscore values ( ' 李四 ', ' 外語 ', ' 85 ');
insert studentscore values ( ' 王五 ', ' 語文 ', ' 70 ');
insert studentscore values ( ' 王五 ', ' 數學 ', ' 71 ');
insert studentscore values ( ' 王五 ', ' 外語 ', ' 75 ');
insert studentscore values ( ' 趙六 ', ' 語文 ', ' 64 ');
insert studentscore values ( ' 趙六 ', ' 數學 ', ' 67 ');
insert studentscore values ( ' 趙六 ', ' 外語 ', ' 76 ');
go
select * from studentscore
go
go
if exists( select id from sysobjects where name = ' studentscore ')
drop table studentscore -- 刪除與實驗沖突的表
go
create table studentscore -- 創建實驗表
(
[ id ] int identity( 1, 1),
[ name ] nvarchar( 20) not null,
subject nvarchar( 20) not null,
score int not null
)
go
select * from studentscore
go
-- 添加實驗數據
insert studentscore values ( ' 張三 ', ' 語文 ', ' 60 ');
insert studentscore values ( ' 張三 ', ' 數學 ', ' 65 ');
insert studentscore values ( ' 張三 ', ' 外語 ', ' 70 ');
insert studentscore values ( ' 李四 ', ' 語文 ', ' 80 ');
insert studentscore values ( ' 李四 ', ' 數學 ', ' 90 ');
insert studentscore values ( ' 李四 ', ' 外語 ', ' 85 ');
insert studentscore values ( ' 王五 ', ' 語文 ', ' 70 ');
insert studentscore values ( ' 王五 ', ' 數學 ', ' 71 ');
insert studentscore values ( ' 王五 ', ' 外語 ', ' 75 ');
insert studentscore values ( ' 趙六 ', ' 語文 ', ' 64 ');
insert studentscore values ( ' 趙六 ', ' 數學 ', ' 67 ');
insert studentscore values ( ' 趙六 ', ' 外語 ', ' 76 ');
go
select * from studentscore
go
我們先利用case when then else end 語句將行轉為列:
select
[
name
],語文
=
case
when subject
=
'
語文
'
then score
else
0
end
from studentscore
group
by
[
name
],subject,score
這里為了好理解只取一列,得到下面的結果
有了語文成績行專列的例子后,我們很容易將其他兩列也添加進來,
select
[
name
],
語文 = case
when subject = ' 語文 ' then score else 0
end,
數學 = case
when subject = ' 數學 ' then score else 0
end,
外語 = case
when subject = ' 外語 ' then score else 0
end
from studentscore
group by [ name ],subject,score
語文 = case
when subject = ' 語文 ' then score else 0
end,
數學 = case
when subject = ' 數學 ' then score else 0
end,
外語 = case
when subject = ' 外語 ' then score else 0
end
from studentscore
group by [ name ],subject,score
下面是查詢后的結果:
現在只要把name相同的行合並到一起就ok了,
select
[
name
],
語文 = max( case
when subject = ' 語文 ' then score else 0
end),
數學 = max( case
when subject = ' 數學 ' then score else 0
end),
外語 = max( case
when subject = ' 外語 ' then score else 0
end)
from studentscore
group by [ name ]
語文 = max( case
when subject = ' 語文 ' then score else 0
end),
數學 = max( case
when subject = ' 數學 ' then score else 0
end),
外語 = max( case
when subject = ' 外語 ' then score else 0
end)
from studentscore
group by [ name ]
好了,看看結果吧.
上面是列數可枚舉時的代碼,很多情況下到底有多少列是動態的或者不可知的.
這個時候需要拼下SQL語句了.
declare
@sql
varchar(
8000)
set @sql = ' select [name], '
select @sql = @sql + ' sum(case subject when ''' +subject + '''
then score else 0 end) as ''' +subject + ''' , '
from ( select distinct subject from studentscore) as a
select @sql = left( @sql, len( @sql) - 1) + ' from studentscore group by [name] '
print @sql -- 查看生成的sql代碼
exec( @sql)
set @sql = ' select [name], '
select @sql = @sql + ' sum(case subject when ''' +subject + '''
then score else 0 end) as ''' +subject + ''' , '
from ( select distinct subject from studentscore) as a
select @sql = left( @sql, len( @sql) - 1) + ' from studentscore group by [name] '
print @sql -- 查看生成的sql代碼
exec( @sql)
打印生成的sql代碼如下:
這個語句還可以再優化些,呵呵.各位大蝦有么有更好的方案?
end
轉自:http://blog.csdn.net/ylqmf/article/details/4438383