Pivot 不能处理多个列开箱即用有几种方法可以解决这个问题:
将此表变量用于所有测试,并请说明您的示例数据始终可复制“n”粘贴。最好的是一个 MCVE(最小完整可验证示例),您可以在其中设置一些类似我的代码。
DECLARE @tbl TABLE(ID INT, Code INT,EmployeeName VARCHAR(100),ExamName VARCHAR(100),Board VARCHAR(100),Result VARCHAR(100));
INSERT INTO @tbl VALUES
(11537,12984,'TheName','SSC','b04','1st')
,(11537,12984,'TheName','HSC','b04','2nd')
,(11537,12984,'TheName','BA(H)','u33','2nd');
这是首先将您的数据连接到一列的代码。这允许PIVOT:
SELECT p.*
FROM
(
SELECT tbl.ID
,tbl.Code
,tbl.EmployeeName
,'Exam_' + CAST(ROW_NUMBER() OVER(PARTITION BY tbl.ID ORDER BY tbl.Code) AS VARCHAR(100)) AS ColName
,ExamName + ' (' + Board + '): ' + Result AS Concatenated
FROM @tbl AS tbl
) AS t
PIVOT
(
MIN(Concatenated) FOR ColName IN(Exam_1,Exam_2,Exam_3 /*add as many as you need*/)
) AS p
结果:
11537 12984 TheName SSC (b04): 1st HSC (b04): 2nd BA(H) (u33): 2nd
下一个代码的作用完全一样,但创建的是 XML 而不是纯文本,这允许之后分离您的数据:
SELECT p.ID
,p.Code
,p.EmployeeName
,E1
,E1.value('(/exam/@ExamName)[1]','varchar(100)') AS ExamName1
,E1.value('(/exam/@Board)[1]','varchar(100)') AS Board1
,E1.value('(/exam/@Result)[1]','varchar(100)') AS Result1
,E2
,E2.value('(/exam/@ExamName)[1]','varchar(100)') AS ExamName2
,E2.value('(/exam/@Board)[1]','varchar(100)') AS Board2
,E2.value('(/exam/@Result)[1]','varchar(100)') AS Result2
,E3
,E3.value('(/exam/@ExamName)[1]','varchar(100)') AS ExamName3
,E3.value('(/exam/@Board)[1]','varchar(100)') AS Board3
,E3.value('(/exam/@Result)[1]','varchar(100)') AS Result3
FROM
(
SELECT tbl.ID
,tbl.Code
,tbl.EmployeeName
,'Exam_' + CAST(ROW_NUMBER() OVER(PARTITION BY tbl.ID ORDER BY tbl.Code) AS VARCHAR(100)) AS ColName
,(SELECT ExamName AS [@ExamName],Board AS [@Board],Result AS [@Result] FOR XML PATH('exam')) AS AsXML
FROM @tbl AS tbl
) AS t
PIVOT
(
MIN(AsXML) FOR ColName IN(Exam_1,Exam_2,Exam_3 /*add as many as you need*/)
) AS p
OUTER APPLY
(
SELECT CAST(p.Exam_1 AS XML) AS E1
,CAST(p.Exam_2 AS XML) AS E2
,CAST(p.Exam_3 AS XML) AS E3
) AS CastedToXml
结果:
11537 12984 TheName <exam ExamName="SSC" Board="b04" Result="1st" /> SSC b04 1st <exam ExamName="HSC" Board="b04" Result="2nd" /> HSC b04 2nd <exam ExamName="BA(H)" Board="u33" Result="2nd" /> BA(H) u33 2nd
这是 old-fashioned-pivot,通常比正常的枢轴要好:
;WITH Numberd AS
(
SELECT *
,ROW_NUMBER() OVER(PARTITION BY tbl.ID ORDER BY tbl.Code) AS Number
FROM @tbl AS tbl
)
SELECT ID,Code,EmployeeName
,MAX(CASE WHEN Number=1 THEN ExamName END) AS ExamName1
,MAX(CASE WHEN Number=1 THEN Board END) AS Board1
,MAX(CASE WHEN Number=1 THEN Result END) AS Result1
,MAX(CASE WHEN Number=2 THEN ExamName END) AS ExamName2
,MAX(CASE WHEN Number=2 THEN Board END) AS Board2
,MAX(CASE WHEN Number=2 THEN Result END) AS Result2
,MAX(CASE WHEN Number=3 THEN ExamName END) AS ExamName3
,MAX(CASE WHEN Number=3 THEN Board END) AS Board3
,MAX(CASE WHEN Number=3 THEN Result END) AS Result3
FROM Numberd
GROUP BY ID,Code,EmployeeName
最后一个选项是动态 SQL...