2005 交叉表。行转列

2000的就不说了,写2005的。

 

--1.行转列

If not object_id('[tb]') is null
Drop table [tb]
Go
create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
Insert tb
Select '张三','语文',60 union all
Select '张三','数学',70 union all
Select '张三','英语',80 union all
Select '张三','物理',90 union all
Select '李四','语文',65 union all
Select '李四','数学',75 union all
Select '李四','英语',85 union all
Select '李四','物理',95
go

--静态查询:
select * from tb pivot(max(分数) for 课程 in(语文,数学,英语,物理)) b
--动态查询:
declare @s varchar(max)
select @s=isnull(@s+',','')+课程 from tb group by 课程
select @s='select * from tb pivot(max(分数) for 课程 in('+@s+'))b'
exec(@s)
/*
姓名 语文 数学 英语 物理
---------- ----------- ----------- ----------- -----------
李四 65 75 85 95
张三 60 70 80 90

(2 行受影响)
*/

--加上总分静态查询
select 姓名,语文,数学,英语,物理,总分
from (select *,总分=sum(分数)over(partition by 姓名) from tb) a
pivot(max(分数) for 课程 in(语文,数学,英语,物理))b

--加上总分动态查询
declare @s varchar(max)
select @s=isnull(@s+',','')+课程 from tb group by 课程
select @s='
select 姓名,'+@s+' from
(select *,总分=sum(分数)over(partition by 姓名) from tb) a
pivot(max(分数) for 课程 in('+@s+'))b'
exec(@s)
/*
姓名 语文 数学 英语 物理 总分
---------- ----------- ----------- ----------- ----------- -----------
张三 60 70 80 90 300
李四 65 75 85 95 320

(2 行受影响)
*/

--2.列转行

If not object_id('tb') is null
Drop table tb
Go
Create table tb(姓名 nvarchar(2),[语文] int,[数学] int,[英语] int,[物理] int)
Insert tb
Select '张三',60,70,80,90 union all
Select '李四',65,75,85,95
Go
--静态查询
select * from tb unpivot(分数 for 课程 in(语文,数学,英语,物理))b
--动态查询
declare @s varchar(max)
select @s=isnull(@s+',','')+name from syscolumns where id=object_id('tb') and name not in('姓名') order by colid
select @s='select * from tb unpivot(分数 for 课程 in('+@s+'))b'
exec(@s)
/*
姓名 分数 课程
------ ---- ------
李四65语文
李四75数学
李四85英语
李四95物理
张三60语文
张三70数学
张三80英语
张三90物理

(8 行受影响)
*/

partition:分组函数

group by 只能得到分组后的统计数据,over partition by 不仅可以得到分组后的统计数据,还可以同时显示明细数据。
group by 是在where子句之后;over partition by 是from子句之前。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值