基于第一列的行到列

时间:2018-03-21 20:35:28

标签: sql sql-server

我有一个像下面这样的学生表

name | subject  | scode
sam  | science  | 20
sam  | computer | 30
sam  | language | 50
sam  | history  | 20
joe  | PET      | 30
joe  | computer | 50
dan  | lab      | 40

我正在寻找下面的输出

name |  20      | 30       | 40    | 50 
sam  |  science | computer | null  | language 
sam  | history  | null     | null  | null
joe  |  null    | PET      | null  | Computer
dan  |  null    | null     | lab   | null

学生有可能在将来再添加一个科目,并且代码对于该特定学生来说是动态的

我尝试使用for xml然而能够​​获得xml的格式但不能转置它。有可能根据输出转动这个有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

我认为与dynamix SQL结合使用可以解决这个问题。我为此创建了一种方法,但这需要进行一些修改:目前它会将第二行与scode 20分组用于学生山姆。尝试一下 - 当你遇到困难时,我会尝试再修改一下:

IF OBJECT_ID('dbo.tbl_test') IS NOT NULL
  DROP TABLE tbl_test
GO

CREATE TABLE tbl_test (
  sName varchar(25)
 ,sSubject varchar(25)
 ,sCode int
)
GO

INSERT INTO tbl_test VALUES
 ('sam', 'science', 20)
,('sam', 'computer', 30)
,('sam', 'language', 50)
,('sam', 'history', 20)
,('joe', 'PET', 30)
,('joe', 'computer', 50)
,('dan', 'lab', 40)


DECLARE @Cols NVARCHAR(MAX);
DECLARE @Qry NVARCHAR(MAX);

SELECT @Cols = STUFF((SELECT DISTINCT ', [' + CAST(scode AS VARCHAR(5)) + ']'
  FROM tbl_test
  ORDER BY 1
  FOR XML PATH ('')), 1, 1, '')

SET @Qry = 'WITH cte AS(
SELECT sName_GRP, sName, ' + @Cols + '
FROM (
  SELECT sName, sCode, sSubject, sName + ' + CHAR(39) + '_' + CHAR(39) + ' + RIGHT(' + char(39) + '0000' + CHAR(39) +' + CAST(ROW_NUMBER() OVER (PARTITION BY sName, sCode ORDER BY sName, sCode) AS VARCHAR(5)), 5) sName_GRP
    FROM tbl_test
) AS j
PIVOT
(
  MAX(sSubject) FOR sCode in (' + @Cols + ')
) AS p
)
SELECT sName, ' + @Cols + '
  FROM cte'

EXEC sp_executesql @Qry