SQL 行列互换,在线等

linger505 2007-04-09 01:18:17
学生 月份 语文 数学
____________________________
张三 200601 80 85
张三 200602 100 85
李四 200601 70 95
李四 200602 80 87

转变成

张三 李四
_____________________________
月份 200601 200601
语文 80 70
数学 85 95

月份 200602 200602
语文 100 80
数学 85 87
...全文
1724 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
linger505 2007-04-11
  • 打赏
  • 举报
回复
回来结贴!
中国风 2007-04-09
  • 打赏
  • 举报
回复
/*
CREATE TABLE tb
(
学生 varchar(10),
月份 varchar(6),
语文 decimal(18,2),
数学 decimal(18,2),
化学 decimal(18,2),
地理 decimal(18,2),
历史 decimal(18,2)
)
insert into tb
select '张三','200601',80,81,82,83,84 union all
select '张三','200602',81,82,82,63,74 union all
select '李四','200601',84,84,82,53,64 union all
select '李四','200602',83,82,85,53,94 union all
select '王二','200601',86,87,86,73,94 union all
select '王二','200602',84,84,82,90,74 union all
select '刘五','200601',70,87,82,87,94
*/

--@s5改处一下排序
declare @s1 varchar(4000),@s2 varchar(4000),@s3 varchar(4000),@s4 varchar(4000),@s5 varchar(4000)

select @s1=isnull(@s1+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 语文 else 0 end)'
from tb group by 学生
set @s1=' select 月份,类型=''语文'','+@s1+' from tb group by 月份'

select @s2=isnull(@s2+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 数学 else 0 end)'
from tb group by 学生
set @s2=' union all select 月份,类型=''数学'','+@s2+' from tb group by 月份 '

select @s3=isnull(@s3+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 化学 else 0 end)'
from tb group by 学生
set @s3=' union all select 月份,类型=''化学'','+@s3+' from tb group by 月份'

select @s4=isnull(@s4+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 地理 else 0 end)'
from tb group by 学生
set @s4=' union all select 月份,类型=''地理'','+@s4+' from tb group by 月份 '

select @s5=isnull(@s5+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 历史 else 0 end)'
from tb group by 学生
set @s5=' union all select 月份,类型=''历史'','+@s5+' from tb group by 月份 order by 类型 asc,月份 asc'--改一下排序


exec(@s1+@s2+@s3+@s4+@s5)
月份 类型 李四 刘五 王二 张三
------ ---- -------------------- -------------------- -------------------- --------------------
200601 地理 53.00 87.00 73.00 83.00
200602 地理 53.00 .00 90.00 63.00
200601 化学 82.00 82.00 86.00 82.00
200602 化学 85.00 .00 82.00 82.00
200601 历史 64.00 94.00 94.00 84.00
200602 历史 94.00 .00 74.00 74.00
200601 数学 84.00 87.00 87.00 81.00
200602 数学 82.00 .00 84.00 82.00
200601 语文 84.00 70.00 86.00 80.00
200602 语文 83.00 .00 84.00 81.00

中国风 2007-04-09
  • 打赏
  • 举报
回复
针对第一个科目生成一个类就行了
(@s1+@s2+@s3+@s4+@s5)
中国风 2007-04-09
  • 打赏
  • 举报
回复
/*
CREATE TABLE tb
(
学生 varchar(10),
月份 varchar(6),
语文 decimal(18,2),
数学 decimal(18,2),
化学 decimal(18,2),
地理 decimal(18,2),
历史 decimal(18,2)
)
insert into tb
select '张三','200601',80,81,82,83,84 union all
select '张三','200602',81,82,82,63,74 union all
select '李四','200601',84,84,82,53,64 union all
select '李四','200602',83,82,85,53,94 union all
select '王二','200601',86,87,86,73,94 union all
select '王二','200602',84,84,82,90,74 union all
select '刘五','200601',70,87,82,87,94
*/


declare @s1 varchar(4000),@s2 varchar(4000),@s3 varchar(4000),@s4 varchar(4000),@s5 varchar(4000)

select @s1=isnull(@s1+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 语文 else 0 end)'
from tb group by 学生
set @s1=' select 月份,类型=''语文'','+@s1+' from tb group by 月份'

select @s2=isnull(@s2+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 数学 else 0 end)'
from tb group by 学生
set @s2=' union all select 月份,类型=''数学'','+@s2+' from tb group by 月份 '

select @s3=isnull(@s3+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 化学 else 0 end)'
from tb group by 学生
set @s3=' union all select 月份,类型=''化学'','+@s3+' from tb group by 月份'

select @s4=isnull(@s4+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 地理 else 0 end)'
from tb group by 学生
set @s4=' union all select 月份,类型=''地理'','+@s4+' from tb group by 月份 '

select @s5=isnull(@s5+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 历史 else 0 end)'
from tb group by 学生
set @s5=' union all select 月份,类型=''历史'','+@s5+' from tb group by 月份 order by 类型 desc,月份 asc'


exec(@s1+@s2+@s3+@s4+@s5)

月份 类型 李四 刘五 王二 张三
------ ---- -------------------- -------------------- -------------------- --------------------
200601 语文 84.00 70.00 86.00 80.00
200602 语文 83.00 .00 84.00 81.00
200601 数学 84.00 87.00 87.00 81.00
200602 数学 82.00 .00 84.00 82.00
200601 历史 64.00 94.00 94.00 84.00
200602 历史 94.00 .00 74.00 74.00
200601 化学 82.00 82.00 86.00 82.00
200602 化学 85.00 .00 82.00 82.00
200601 地理 53.00 87.00 73.00 83.00
200602 地理 53.00 .00 90.00 63.00

linger505 2007-04-09
  • 打赏
  • 举报
回复
有兴趣的人可以用我的这个SQL语气去生成表数据,然后用上述的方法看能不能实现以下的效果!
CREATE TABLE tb
(
学生 varchar(10),
月份 varchar(6),
语文 decimal(18,2),
数学 decimal(18,2),
化学 decimal(18,2),
地理 decimal(18,2),
历史 decimal(18,2)
)
insert into tb
select '张三','200601',80,81,82,83,84 union all
select '张三','200602',81,82,82,63,74 union all
select '李四','200601',84,84,82,53,64 union all
select '李四','200602',83,82,85,53,94 union all
select '王二','200601',86,87,86,73,94 union all
select '王二','200602',84,84,82,90,74 union all
select '刘五','200601',70,87,82,87,94

学生 月份 语文 数学 化学 地理 历史
_______________________________________________________
张三 200601 80.00 81.00 82.00 83.00 84.00
张三 200602 81.00 82.00 82.00 63.00 74.00
李四 200601 84.00 84.00 82.00 53.00 64.00
李四 200602 83.00 82.00 85.00 53.00 94.00
王二 200601 86.00 87.00 86.00 73.00 94.00
王二 200602 84.00 84.00 82.00 90.00 74.00
刘五 200601 70.00 87.00 82.00 87.00 94.00

月份 科目 李四 刘五 王二 张三
_______________________________________________
200601 地理 53.00 87.00 73.00 83.00
200602 地理 53.00 .00 90.00 63.00
200601 化学 82.00 82.00 86.00 82.00
200602 化学 85.00 .00 82.00 82.00
200601 历史 64.00 94.00 94.00 84.00
200602 历史 94.00 .00 74.00 74.00
200601 数学 84.00 87.00 87.00 81.00
200602 数学 82.00 .00 84.00 82.00
200601 语文 84.00 70.00 86.00 80.00
200602 语文 83.00 .00 84.00 81.00

linger505 2007-04-09
  • 打赏
  • 举报
回复
感谢大家的回答,
To dawugui(潇洒老乌龟)
你写的这个不是我要的效果
To:roy_88(中国风_燃烧你的激情!!!)
效果跟我要的相近,不过代码比我的好像要少,具体我没有去测
总之很感谢大家的回答!
我自己的写的那个已经可以达到我的效果了,所以任务要紧,暂时采用我自己的方法!
中国风 2007-04-09
  • 打赏
  • 举报
回复
create table ta(学生 varchar(5), 月份 int, 语文 int, 数学 int)
insert ta select '张三', 200601, 80, 85
insert ta select '张三', 200602, 100, 85
insert ta select '李四', 200601, 70, 95
insert ta select '李四', 200602, 80, 87

declare @s varchar(4000),@s2 varchar(4000),@s3 varchar(4000)

select @s=isnull(@s+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 月份 else 0 end)'
from ta group by 学生
set @s='select 类型=''月份'','+@s+',月份 from ta group by 月份'

select @s2=isnull(@s2+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 语文 else 0 end)'
from ta group by 学生
set @s2=' union all select 类型=''语文'','+@s2+',月份 from ta group by 月份'

select @s3=isnull(@s3+',','')+quotename(学生)+'=max(case 学生 when '''+学生+''' then 数学 else 0 end)'
from ta group by 学生
set @s3=' union all select 类型=''数学'','+@s3+',月份 from ta group by 月份 order by 月份 asc,类型 desc'

exec(@s+@s2+@s3)

类型 李四 张三 月份
---- ----------- ----------- -----------
月份 200601 200601 200601
语文 70 80 200601
数学 95 85 200601
月份 200602 200602 200602
语文 80 100 200602
数学 87 85 200602

dawugui 2007-04-09
  • 打赏
  • 举报
回复
普通行列转换

假设有张学生成绩表(t)如下

Name Subject Result
张三 语文  73
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94

想变成
姓名 语文 数学 物理
张三 73  83  93
李四 74  84  94

create table #t
(
Name varchar(10) ,
Subject varchar(10) ,
Result int
)

insert into #t(Name , Subject , Result) values('张三','语文','73')
insert into #t(Name , Subject , Result) values('张三','数学','83')
insert into #t(Name , Subject , Result) values('张三','物理','93')
insert into #t(Name , Subject , Result) values('李四','语文','74')
insert into #t(Name , Subject , Result) values('李四','数学','83')
insert into #t(Name , Subject , Result) values('李四','物理','93')

declare @sql varchar(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , sum(case Subject when ''' + Subject + ''' then Result end) [' + Subject + ']'
from (select distinct Subject from #t) as a
set @sql = @sql + ' from #t group by name'
exec(@sql)

drop table #t

--结果
姓名 数学 物理 语文
---------- ----------- ----------- -----------
李四 83 93 74
张三 83 93 73

----------------------------------------------------
如果上述两表互相换一下:即

姓名 语文 数学 物理
张三 73  83  93
李四 74  84  94

想变成
Name Subject Result
张三 语文  73
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94

create table #t
(
姓名 varchar(10) ,
语文 int ,
数学 int ,
物理 int
)

insert into #t(姓名 , 语文 , 数学 , 物理) values('张三',73,83,93)
insert into #t(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)

select 姓名 as Name,'语文' as Subject,语文 as Result from #t union
select 姓名 as Name,'数学' as Subject,数学 as Result from #t union
select 姓名 as Name,'物理' as Subject,物理 as Result from #t
order by 姓名 desc

drop table #t

--结果
Name Subject Result
---------- ------- -----------
张三 数学 83
张三 物理 93
张三 语文 73
李四 数学 84
李四 物理 94
李四 语文 74

(所影响的行数为 6 行)
linger505 2007-04-09
  • 打赏
  • 举报
回复
自己写出来了!
共享一下
大家看看有没有错!
declare @sql varchar(8000) ,@sql1 varchar(8000)
set @sql = 'select 月份,科目,'
select @sql=@sql+'sum(' + 学生+') as '''+ 学生+ ''' ,' from (select distinct 学生 from tb )a
set @sql=left(@sql,len(@sql)-1) + ' from ('

--语文
set @sql1='select distinct 月份,''语文'' as ''科目'','
select @sql1=@sql1+'case 学生 when '''+ 学生 + ''' then (select 语文 from tb where 学生=a.学生 and 月份=a.月份) else 0 end '''+ 学生+''','
from (select distinct 学生 from tb) a
set @sql1=left(@sql1,len(@sql1)-1) + ' from tb a union all '
--数学
set @sql1=@sql1+' select distinct 月份,''数学'' as ''科目'','
select @sql1=@sql1+'case 学生 when '''+ 学生 + ''' then (select 数学 from tb where 学生=a.学生 and 月份=a.月份) else 0 end '''+ 学生+''','
from (select distinct 学生 from tb) a
set @sql1=left(@sql1,len(@sql1)-1) + ' from tb a union all '
--化学
set @sql1=@sql1+' select distinct 月份,''化学'' as ''科目'','
select @sql1=@sql1+'case 学生 when '''+ 学生 + ''' then (select 化学 from tb where 学生=a.学生 and 月份=a.月份) else 0 end '''+ 学生+''','
from (select distinct 学生 from tb) a
set @sql1=left(@sql1,len(@sql1)-1) + ' from tb a union all '
--地理
set @sql1=@sql1+' select distinct 月份,''地理'' as ''科目'','
select @sql1=@sql1+'case 学生 when '''+ 学生 + ''' then (select 地理 from tb where 学生=a.学生 and 月份=a.月份) else 0 end '''+ 学生+''','
from (select distinct 学生 from tb) a
set @sql1=left(@sql1,len(@sql1)-1) + ' from tb a union all '
--历史
set @sql1=@sql1+' select distinct 月份,''历史'' as ''科目'','
select @sql1=@sql1+'case 学生 when '''+ 学生 + ''' then (select 历史 from tb where 学生=a.学生 and 月份=a.月份) else 0 end '''+ 学生+''','
from (select distinct 学生 from tb) a
set @sql1=left(@sql1,len(@sql1)-1) + ' from tb a '
set @sql=@sql+ @sql1 + ') aa group by 月份,科目
order by 科目 ,月份'
--print @sql1
exec (@sql)
sp4 2007-04-09
  • 打赏
  • 举报
回复
怎么也得是2个查询,然后union all

34,594

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧