sql 行列互转

1、行转列

现有数据:

期望数据:

 

1.1建表建数据

 IF OBJECT_ID('temp_20170701','u') IS NOT NULL DROP TABLE temp_20170701
 CREATE TABLE temp_20170701 (
 ID INT PRIMARY KEY IDENTITY(1,1),
 NAME  NVARCHAR(50),
 Subjectname NVARCHAR(50),
 Score INT
 )


INSERT dbo.temp_20170701( Name, subjectname, Score )
SELECT 'A','语文','20' UNION
SELECT 'A','数学','30' UNION
SELECT 'A','英语','40' UNION 
SELECT 'B','语文','50' UNION
SELECT 'B','数学','60' UNION
SELECT 'B','英语','70' UNION 
SELECT 'C','语文','80' UNION
SELECT 'C','数学','90' UNION
SELECT 'C','英语','100' UNION
SELECT 'D','英语','100' 

 

1.2 .1 静态实现

 SELECT Name , MAX(CASE WHEN subjectname='语文' THEN Score ELSE 0 END)语文 ,
 MAX(CASE WHEN subjectname='数学' THEN Score  ELSE 0 END)数学,
 MAX(CASE WHEN subjectname='英语' THEN Score  ELSE 0 END)英语
 FROM dbo.temp_20170701 GROUP BY Name

1.2.2 动态实现 

 DECLARE @sql varchar(500) 
 SET @sql='select Name ' 
 SELECT @sql=@sql+',max(case subjectname when '''+subjectname+''' then Score else 0 end)['+subjectname+']'
 FROM(SELECT DISTINCT subjectname FROM temp_20170701)a 
 SET @sql=@sql+' from temp_20170701 group by Name'
 --SELECT @sql
 EXEC(@sql)

 

2、行转列 逗号隔开

现有数据如1的第一张图

期望数据:

2.1、使用xml path

 SELECT Name ,Score=STUFF((SELECT ','+CONVERT(NVARCHAR(max),Score) FROM temp_20170701 t1 WHERE t1.NAME=t2.NAME FOR XML PATH('')),1,1,'')
 FROM temp_20170701 t2 GROUP BY t2.NAME  

2.2、使用 函数

CREATE FUNCTION [dbo].[HConvertL]
(
@GroupId nvarchar(max)
)
RETURNS [nvarchar](max)
AS
BEGIN
DECLARE @ReturnValue [nvarchar](max)
SET @ReturnValue = ''
SELECT @ReturnValue=@ReturnValue + RTRIM(LTRIM(Score)) + ','
FROM temp_20170701
WHERE NAME = @GroupId
SET @ReturnValue = ','+@ReturnValue --substring(@ReturnValue,1,len(@ReturnValue)-1)
RETURN @ReturnValue
END

SELECT DISTINCT Name,dbo.[HConvertL](name) Score FROM temp_20170701

 

3、列转行

原始数据:

期望数据:

3.1建表建数据

IF OBJECT_ID('tempdb..#temp_20170701_02','U') IS NOT NULL DROP TABLE #temp_20170701_02
CREATE TABLE #temp_20170701_02
(
ID INT PRIMARY KEY IDENTITY(1,1),
NAME NVARCHAR(50),
语文 INT NOT NULL DEFAULT 0,
数学 INT NOT NULL DEFAULT 0,
英语 INT NOT NULL DEFAULT 0
)
INSERT #temp_20170701_02( NAME, 语文, 数学, 英语 )
SELECT 'A',20,30,40 UNION
SELECT 'B',50,60,70 UNION
SELECT 'C',80,90,100 UNION
SELECT 'D',100,0,0 

3.2 使用UNPIVOT实现

SELECT  Name ,
        SubjectName ,
        Score
FROM    #temp_20170701_02 UNPIVOT ( Score FOR SubjectName IN ( 语文, 数学, 英语 ) ) #temp_20170701_02 

  

 

posted @ 2017-07-01 11:00  RJXS  阅读(306)  评论(0编辑  收藏  举报