sql 行列转换

 -----------------------------------------------一:列转行

CREATE TABLE [StudentInfo](
[SId] [varchar](10) NOT NULL primary key,
[SName] [varchar](50) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [StudentInfo]([SId],[SName]) VALUES('S001','张三') 
INSERT INTO [StudentInfo]([SId],[SName]) VALUES('S002','李四')
INSERT INTO [StudentInfo]([SId],[SName]) VALUES('S003','王五')
INSERT INTO [StudentInfo]([SId],[SName]) VALUES('S004','赵六')
GO
CREATE TABLE [CourseInfo](
[CId] [varchar](10) NOT NULL primary key,
[CName] [varchar](50) NOT NULL
) ON [PRIMARY]
GO
INSERT INTO [CourseInfo]([CId],[CName]) VALUES('C001','数学')
INSERT INTO [CourseInfo]([CId],[CName]) VALUES('C002','语文')
INSERT INTO [CourseInfo]([CId],[CName]) VALUES('C003','英语')
INSERT INTO [CourseInfo]([CId],[CName]) VALUES('C004','历史')
INSERT INTO [CourseInfo]([CId],[CName]) VALUES('C005','化学')
GO
CREATE TABLE [AchievementInfo](
[SId] [varchar](10) NOT NULL,
[CId] [varchar](10) NOT NULL,
[Score] [float] NULL
 
PRIMARY KEY NONCLUSTERED ([SId],[CId]),
FOREIGN KEY ([SId]) REFERENCES [StudentInfo]([SId]),
FOREIGN KEY ([CId]) REFERENCES [CourseInfo]([CId]) 
ON [PRIMARY]
GO
INSERT INTO [AchievementInfo]([SId],[CId],[Score]) VALUES('S001','C001',80)
INSERT INTO [AchievementInfo]([SId],[CId],[Score]) VALUES('S001','C002',70)
INSERT INTO [AchievementInfo]([SId],[CId],[Score]) VALUES('S002','C002',75)
INSERT INTO [AchievementInfo]([SId],[CId],[Score]) VALUES('S002','C003',72)
INSERT INTO [AchievementInfo]([SId],[CId],[Score]) VALUES('S003','C001',60)
 
GO
select * from StudentInfo
--SId SName
--S001 张三
--S002 李四
--S003 王五
--S004 赵六
 
select * from CourseInfo
--CId CName
--C001 数学
--C002 语文
--C003 英语
--C004 历史
--C005 化学
 
select * from AchievementInfo
--SId CId Score
--S001 C001 80
--S001 C002 70
--S002 C002 75
--S002 C003 72
--S003 C001 60
 
--1.case方式(静态)
select isnull(SName,'课程总分') as 姓名,
SUM(case CName when '化学' then [Score] else 0 end) 化学,
SUM(case CName when '历史' then [Score] else 0 end) 历史,
SUM(case CName when '数学' then [Score] else 0 end) 数学,
SUM(case CName when '英语' then [Score] else 0 end) 英语,
SUM(case CName when '语文' then [Score] else 0 end) 语文,
SUM([Score]) as 个人总分
from (
select a.SName,b.CName,ISNULL(c.Score,0) Score from [StudentInfo] a cross join [CourseInfo] b 
left join [AchievementInfo] c on c.CId=b.CId and c.SId=a.SId
) d
group by SName
with rollup
--姓名   化学 历史 数学   英语 语文 个人总分
--李四 0 0 0 72 75 147
--王五 0 0 60 0 0 60
--张三 0 0 80 0 70 150
--赵六 0 0 0 0 0 0
--课程总分  0 0 140 72 145 357
 
--case方式(动态)
declare @sql varchar(1000),@sqlSum varchar(500)
select @sql=isnull(@sql+',','')+'sum(case CName when '''+[CName]+''' then Score else 0 end) '+[CName] from [CourseInfo] group by [CName]
set @sql='select isnull(SName,''课程总分'') as 姓名,
'+@sql+',
SUM([Score]) as 个人总分
from (
select a.SName,b.CName,ISNULL(c.Score,0) Score from [StudentInfo] a cross join [CourseInfo] b 
left join [AchievementInfo] c on c.CId=b.CId and c.SId=a.SId
) d
group by SName
with rollup'
exec (@sql)
--姓名   化学 历史 数学   英语 语文 个人总分
--李四 0 0 0 72 75 147
--王五 0 0 60 0 0 60
--张三 0 0 80 0 70 150
--赵六 0 0 0 0 0 0
--课程总分  0 0 140 72 145 357
 
--2.pivot方式(静态)
select ISNULL(SName,'课程总分') 姓名,SUM(化学) 化学,SUM(历史) 历史,SUM(数学) 数学,SUM(英语) 英语,SUM(语文) 语文
,(SUM(数学)+SUM(语文)+SUM(英语)+SUM(历史)+SUM(化学)) 个人总分
from (
select a.SName,b.CName,ISNULL(c.Score,0) Score from [StudentInfo] a cross join [CourseInfo] b 
left join [AchievementInfo] c on c.CId=b.CId and c.SId=a.SId
) d pivot (sum(Score) for CName in (
数学,语文,英语,历史,化学
))e
group by SName
with rollup
--姓名   化学 历史 数学   英语 语文 个人总分
--李四 0 0 0 72 75 147
--王五 0 0 60 0 0 60
--张三 0 0 80 0 70 150
--赵六 0 0 0 0 0 0
--课程总分  0 0 140 72 145 357
 
--pivot方式(动态)
declare @sql varchar(500),@sqlSum varchar(500),@sqlSumAdd varchar(500)
select @sql=isnull(@sql+',','')+[CName] from [CourseInfo] group by [CName]
select @sqlSum=isnull(@sqlSum+',','')+'sum('+[CName]+') '+[CName]+''  from [CourseInfo] group by [CName]
select @sqlSumAdd=isnull(@sqlSumAdd+'+','')+'sum('+[CName]+')'  from [CourseInfo] group by [CName]
set @sql='select ISNULL(SName,''个人总分'') 姓名,'+@sqlSum+',('+@sqlSumAdd+') 课程总分
from (
select a.SName,b.CName,ISNULL(c.Score,0) Score from [StudentInfo] a cross join [CourseInfo] b 
left join [AchievementInfo] c on c.CId=b.CId and c.SId=a.SId
) d pivot (sum(Score) for CName in ('+@sql+'))e
group by SName
with rollup'
exec (@sql)
 
--姓名   化学 历史 数学   英语 语文 个人总分
--李四 0 0 0 72 75 147
--王五 0 0 60 0 0 60
--张三 0 0 80 0 70 150
--赵六 0 0 0 0 0 0
--课程总分  0 0 140 72 145 357
------------------------------------------------------------------------------------------
--3. 行列转换--合并
--drop Function KFReturn
create Function KFReturn(@Class Varchar(50))
Returns Varchar(8000)
as 
Begin
Declare @str Varchar(8000)
Set @str = ''
Select @str = @str + cast(CId as Varchar(50))+':'+ cast(Score as Varchar(50)) + ',' from AchievementInfo Where SId = @Class
Set @str = SubString(@str,1,len(@str)-1)
Return(@str)
End
--调用自定义函数得到结果
select Distinct SId,dbo.KFReturn(SId) MergerColumn From AchievementInfo
 
--CId MergerColumn
--S001 C001:80,C002:70
--S002 C002:75,C003:72
--S003 C001:60
-----------------------------------------------二:行转列
--4.unpivot方式
select [SId],keys,value from 
(select [SId],CId,CAST(Score AS varchar(10)) Score from AchievementInfo) p 
unpivot(value for keys in(CId,Score)) as u
order by [SId]
 
--SId keys value
--S001 CId C001
--S001 Score 80
--S001 CId C002
--S001 Score 70
--S002 CId C002
--S002 Score 75
--S002 CId C003
--S002 Score 72
--S003 CId C001
--S003 Score 60

你可能感兴趣的:(sql,数据库)