SQL SERVER 行列轉換(動態)


行轉列測試數據:

--測試數據
if not object_id(N'Tempdb..#T') is null
	drop table #T
Go
Create table #T([Name] nvarchar(22),[Subject] nvarchar(22),[Score] int)
Insert #T
select N'李四',N'語文',60 union all
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'英語',70
Go
--測試數據結束

動態寫法(加上了總分和平均分):

DECLARE @sql VARCHAR(MAX)
SET @sql = 'select Name'
SELECT  @sql = @sql + ',max(case Subject when ''' + Subject
        + ''' then Score else 0 end)[' + Subject + ']'
FROM    ( SELECT DISTINCT
                    Subject
          FROM      #T
        ) a
SET @sql = @sql
    + ',sum(Score) 總分,cast(avg(Score*1.0) as decimal(18,2)) 平均分 from #T group by Name'
EXEC(@sql)

動態的也可以使用pivot:

DECLARE @sql VARCHAR(MAX)
SELECT @sql=isnull(@sql+',','')+Subject FROM #T GROUP BY Subject
SET @sql='select m.* , n.總分, n.平均分 from
(select * from (select * from #T) a pivot (max(Score) for Subject in ('+@sql+')) b) m ,
(select Name,sum(Score)總分, cast(avg(Score*1.0) as decimal(18,2))平均分 from #T group by Name) n
where m.Name= n.Name'
exec(@sql)

列轉行的測試數據:

--測試數據  
if not object_id(N'Tt') is null
drop table Tt
Go
Create table Tt([姓名] nvarchar(22),[語文] int,[數學] int,[英語] int)
Insert Tt
select N'張三',60,70,80 union all 
select N'李四',90,80,70
Go
--測試數據結束 

 動態寫法:

DECLARE @sql VARCHAR(8000)
SELECT @sql=isnull(@sql+' union all ','')+' select 姓名, [課程]='
+quotename(Name,'''')+' , [分數] = '+quotename(Name)+' from T'
FROM syscolumns
WHERE Name!='姓名' AND ID=object_id('T')--表名tb,不包含列名為姓名的其他列
ORDER BY colid
EXEC(@sql+' order by 姓名')

 同樣的動態寫法也可以使用unpivot:

DECLARE @sql VARCHAR(8000)
SELECT @sql=isnull(@sql+',','')+quotename(Name)
FROM syscolumns
WHERE ID=object_id('T')AND Name NOT IN('姓名')
ORDER BY Colid
SET @sql='select 姓名,[課程],[分數] from T unpivot ([分數] for [課程] in('+@sql+'))b'
exec(@sql)

  

  

  

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM