34,591
社区成员
发帖
与我相关
我的任务
分享
--表B
--name 语文 数学 英语
----------------------------------
--张三 150 170 160
--李四 140 140 150
if object_id('A') is not null
drop table A
Go
Create table A([name] nvarchar(2),[course] nvarchar(2),[score] smallint)
Insert into A
Select N'张三',N'语文',70
Union all Select N'张三',N'语文',80
Union all Select N'张三',N'数学',90
Union all Select N'张三',N'数学',80
Union all Select N'张三',N'英语',90
Union all Select N'张三',N'英语',70
Union all Select N'李四',N'语文',60
Union all Select N'李四',N'语文',80
Union all Select N'李四',N'数学',90
Union all Select N'李四',N'数学',50
Union all Select N'李四',N'英语',80
Union all Select N'李四',N'英语',70
;WITH cte AS (
select name,course,SUM(score) AS score from A
GROUP BY name,course
)
SELECT name,语文,数学,英语 FROM cte
PIVOT (
max(score) FOR course IN(语文,数学,英语)
) AS p
Go
--创建一个数据库来存放原始数据
create database testcs
on
(name = 'testcs',filename = 'F:\fyj\sql serve 2005\database\testcs.mdf')
log on
(name = 'testcs_log',filename = 'F:\fyj\sql serve 2005\database\testcs_log.ldf')
--创建一张表来存放你的原始数据
use testcs
create table sc(cname varchar(20),course varchar(10),grade int)
alter table sc alter column cname
insert into sc(cname,course,grade)
values('李四','英语','70')
--。。。这里有12条记录 我就不列出来了,我全部都插入进去了
--创建一张临时表 专门用来保存张三的信息
create table sctemp(cname varchar(20),course varchar(10),grade int)
insert into sctemp
select * from sc where cname = '张三'
--创建一张临时表 用来保存李四的信息
create table sctemp1(cname varchar(20),course varchar(10),grade int)
insert into sctemp1
select * from sc where cname = '李四'
--将SC表的信息清空
delete from sc
--利用group by和sum函数对张三信息处理后插入sc表
insert into sc
select cname,course, sum(grade) as '总成绩' from sctemp group by course,course,cname
--同理将李四的信息处理插入SC表
insert into sc
select cname,course, sum(grade) as '总成绩' from sctemp1 group by course,course,cname
--最后将sctemp表 和 sctemp1表删除
drop table sctemp
drop table sctemp1
--这个不理解的话 就照下面的子查询运行一遍就知道了
select grade1 '数学' ,grade2 '英语',grade3 '语文'
from
(select * from
(select a.cname cname1,a.course course1,a.grade grade1,b.cname cname2,b.course course2,b.grade grade2,c.cname cname3,c.course course3,c.grade grade3
from sc as a,sc as b, sc as c where a.cname = b.cname and b.cname = c.cname)temp
where temp.course1<>temp.course2 and temp.course2<>temp.course3 and temp.course1<>temp.course3)temp1
where course1 = '数学' and course2 = '英语'
--将以上的三个子查询分别运行一次你就明白了
temp (select a.cname cname1,a.course course1,a.grade grade1,b.cname cname2,b.course course2,b.grade grade2,c.cname cname3,c.course course3,c.grade grade3
from sc as a,sc as b, sc as c where a.cname = b.cname and b.cname = c.cname)
temp1 select * from temp
where temp.course1<>temp.course2 and temp.course2<>temp.course3 and temp.course1<>temp.course3)
select grade1 '数学' ,grade2 '英语',grade3 '语文' from temp1
where course1 = '数学' and course2 = '英语'
--楼上的解法我是没看懂
--我的做法是将张三和李四的成绩分开
--将他们的纪录分别查到两张表里
--在对两张表里的数据利用group by句子和sum来求和
--最后将两张表的查询结果插入一张表。
--OK
--寝室11点断网 没时间发SQL代码了。
if object_id('[tb]') is not null drop table [tb]
go
create table [tb] (name nvarchar(4),course nvarchar(4),score int)
insert into [tb]
select '张三','语文',70 union all
select '张三','语文',80 union all
select '张三','数学',90 union all
select '张三','数学',80 union all
select '张三','英语',90 union all
select '张三','英语',70 union all
select '李四','语文',60 union all
select '李四','语文',80 union all
select '李四','数学',90 union all
select '李四','数学',50 union all
select '李四','英语',80 union all
select '李四','英语',70
select * from [tb]
select name ,SUM(case when course ='语文' then score else 0 end ) as '语文',
SUM(case when course ='数学' then score else 0 end ) as '数学',
SUM(case when course ='英语' then score else 0 end ) as '英语'
from TB
group by name
/*
name 语文 数学 英语
---- ----------- ----------- -----------
李四 140 140 150
张三 150 170 160
(2 行受影响)
create table 表A
(name varchar(8), course varchar(6), score int)
insert into 表A
select '张三', '语文', 70 union all
select '张三', '语文', 80 union all
select '张三', '数学', 90 union all
select '张三', '数学', 80 union all
select '张三', '英语', 90 union all
select '张三', '英语', 70 union all
select '李四', '语文', 60 union all
select '李四', '语文', 80 union all
select '李四', '数学', 90 union all
select '李四', '数学', 50 union all
select '李四', '英语', 80 union all
select '李四', '英语', 70
select name,[语文],[数学],[英语]
from
(select name,course,sum(score) score
from 表A group by name,course) t1
pivot(max(score) for course in([语文],[数学],[英语])) t2
order by name desc
name 语文 数学 英语
-------- ----------- ----------- -----------
张三 150 170 160
李四 140 140 150
(2 row(s) affected)
--> 测试数据:[test]
go
if object_id('[test]') is not null
drop table [test]
go
create table [test](
[name] varchar(4),
[course] varchar(4),
[score] int
)
go
insert [test]
select '张三','语文',70 union all
select '张三','语文',80 union all
select '张三','数学',90 union all
select '张三','数学',80 union all
select '张三','英语',90 union all
select '张三','英语',70 union all
select '李四','语文',60 union all
select '李四','语文',80 union all
select '李四','数学',90 union all
select '李四','数学',50 union all
select '李四','英语',80 union all
select '李四','英语',70
--2000动态转换
declare @str varchar(2000)
set @str=''
select
@str=@str+','+[course]+'=max(case when [course]='
+''''+[course]+''''+' then [score] else 0 end)'
from
[test]
group by
[course]
exec('select [name] 姓名'+@str+' from [test] group by [name]')
/*
姓名 数学 英语 语文
李四 90 80 80
张三 90 90 80
*/
--2005以上版本
select
*
from
[test]
pivot
(max([score]) for [course] in([数学],[英语],[语文]))b
/*
name 数学 英语 语文
李四 90 80 80
张三 90 90 80
*/
--行列互转
--摘自中国风博客,引用请标明内容来源
--1、行换列
if object_id('Class') is not null
drop table Class
Go
Create table Class(
[Student] nvarchar(2),
[Course] nvarchar(2),
[Score] int)
Insert Class
select N'张三',N'语文',78 union all
select N'张三',N'数学',87 union all
select N'张三',N'英语',82 union all
select N'张三',N'物理',90 union all
select N'李四',N'语文',65 union all
select N'李四',N'数学',77 union all
select N'李四',N'英语',65 union all
select N'李四',N'物理',85
Go
--2000方法:
--动态:
declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='
+quotename([Course],'''')+' then [Score] else 0 end)'
from
Class group by[Course]
--select @s
exec('select [Student]'+@s+' from Class group by [Student]')
--生成静态:
select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end)
from
Class
group by [Student]
GO
--动态:
declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
select @s
exec('select * from Class pivot (max([Score]) for [Course] in('+@s+'))b')
--生成静态:
select *
from
Class
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b
--生成格式:
/*
Student 数学 物理 英语 语文
------- ----------- ----------- ----------- -----------
李四 77 85 65 65
张三 87 90 82 78
(2 行受影响)
*/
go
--加上总成绩(学科平均分)
--2000方法:
--动态:
declare @s nvarchar(4000)
set @s=''
Select @s=@s+','+quotename([Course])+'=max(case when [Course]='+quotename([Course],'''')+'then [Score] else 0 end)'
from Class group by[Course]
exec('select [Student]'+@s+',[总成绩]=sum([Score]) from Class group by [Student]')--加多一列(学科平均分用avg([Score]))
生成动态:
select
[Student],
[数学]=max(case when [Course]='数学' then [Score] else 0 end),
[物理]=max(case when [Course]='物理' then [Score] else 0 end),
[英语]=max(case when [Course]='英语' then [Score] else 0 end),
[语文]=max(case when [Course]='语文' then [Score] else 0 end),
[总成绩]=([Score]) --加多一列(学科平均分用avg([Score]))
from
Class
group by [Student]
go
--2005方法:
动态:
declare @s nvarchar(4000)
Select @s=isnull(@s+',','')+quotename([Course]) from Class group by[Course]
--isnull(@s+',','') 去掉字符串@s中第一个逗号
exec('select [Student],'+@s+',[总成绩] from (select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a
pivot (max([Score]) for [Course] in('+@s+'))b ')
--生成静态:
select
[Student],[数学],[物理],[英语],[语文],[总成绩]
from
(select *,[总成绩]=sum([Score])over(partition by [Student]) from Class) a --平均分时用avg([Score])
pivot
(max([Score]) for [Course] in([数学],[物理],[英语],[语文]))b
生成格式:
/*
Student 数学 物理 英语 语文 总成绩
------- ----------- ----------- ----------- ----------- -----------
李四 77 85 65 65 292
张三 87 90 82 78 337
(2 行受影响)
*/
go
--2、列转行
if not object_id('Class') is null
drop table Class
Go
Create table Class([Student] nvarchar(2),[数学] int,[物理] int,[英语] int,[语文] int)
Insert Class
select N'李四',77,85,65,65 union all
select N'张三',87,90,82,78
Go
--2000:
动态:
declare @s nvarchar(4000)
select @s=isnull(@s+' union all ','')+'select [Student],[Course]='+quotename(Name,'''')--isnull(@s+' union all ','') 去掉字符串@s中第一个union all
+',[Score]='+quotename(Name)+' from Class'
from syscolumns where ID=object_id('Class') and Name not in('Student')--排除不转换的列
order by Colid
exec('select * from ('+@s+')t order by [Student],[Course]')--增加一个排序
生成静态:
select *
from (select [Student],[Course]='数学',[Score]=[数学] from Class union all
select [Student],[Course]='物理',[Score]=[物理] from Class union all
select [Student],[Course]='英语',[Score]=[英语] from Class union all
select [Student],[Course]='语文',[Score]=[语文] from Class)t
order by [Student],[Course]
go
--2005:
动态:
declare @s nvarchar(4000)
select @s=isnull(@s+',','')+quotename(Name)
from syscolumns where ID=object_id('Class') and Name not in('Student')
order by Colid
exec('select Student,[Course],[Score] from Class unpivot ([Score] for [Course] in('+@s+'))b')
go
select
Student,[Course],[Score]
from
Class
unpivot
([Score] for [Course] in([数学],[物理],[英语],[语文]))b
生成格式:
/*
Student Course Score
------- ------- -----------
李四 数学 77
李四 物理 85
李四 英语 65
李四 语文 65
张三 数学 87
张三 物理 90
张三 英语 82
张三 语文 78
*/