SQL Server - 使用现有表的Dynamic Pivot

时间:2016-07-21 11:25:08

标签: sql-server pivot

我有以下查询

obj1.add("hello")

返回以下结果: Results 但是我想使用Pivot,以便每个用户的信息(特别是他们接受培训的级别在列中显示为一个值(列标题是用户名)。

我想忽略CurrentRev,而每个程序的每个修订版都有1行(如果没有用户接受过当前版本的培训 - 用户是否接受过以前对该程序的任何修订的培训,那么应该在那里作为空行),如下所示:

enter image description here

我认为我需要使用一个支点,虽然我之前从未尝试过,加上我在网上看到的例子似乎使用了一个静态列表来旋转列,而我想要使用Users表中的所有记录。

我应该指出,在数据网格中显示结果时,为了清晰起见,它会被着色。

我将如何尝试这个?

更新:我已达到此查询

SELECT CONCAT(RIGHT('00' + CONVERT(VARCHAR(2),Procedures.SeriesNum),2),'-',RIGHT('0000' + CONVERT(VARCHAR(4),Procedures.ProcNum),4)) AS 'Procedure',
Procedures.Description,
Procedures.CurrentRev,
Procedures.DayToDayLevel,
Procedures.MaxLevel,
Users.Username,
UsersProcedures.RevTrained,
UsersProcedures.LevelTrained
FROM Procedures
CROSS JOIN Users
LEFT JOIN UsersProcedures ON UsersProcedures.Username = Users.Username AND Procedures.SeriesNum = UsersProcedures.SeriesNum AND Procedures.ProcNum = UsersProcedures.ProcNum

这给了我这个:

enter image description here

然而,我仍然希望将结果分组,类似于我的第二个屏幕截图。即,如果至少有一个用户已经接受过特定修订的培训,那么也不要为该修订显示另一个空行。

如果RevTrained为NULL,则在其位置显示CurrentRev。

1 个答案:

答案 0 :(得分:0)

好的,这是完成的解决方案,使用动态查询获取所有用户,以及IF语句来解决上述问题:

  

如果至少有一个用户已经接受过特定修订的培训,那么也不要为该修订显示另一个空行。   此外,如果RevTrained为NULL,则在其位置显示CurrentRev。

DECLARE @users AS VARCHAR(MAX),@query AS VARCHAR(MAX)
SELECT @users  = STUFF((SELECT ',' + CONCAT('[',Username,']') FROM Users FOR XML PATH(''),TYPE).value('.', 'VARCHAR(MAX)'),1,1,'')
SET @query = 'SELECT *
FROM (SELECT CONCAT(RIGHT(''00'' + CONVERT(VARCHAR(2),Procedures.SeriesNum),2),''-'',RIGHT(''0000'' + CONVERT(VARCHAR(4),Procedures.ProcNum),4)) AS ''Procedure Number'',
CASE WHEN UsersProcedures.RevTrained IS NULL THEN Procedures.CurrentRev ELSE UsersProcedures.RevTrained END AS ''Revision'',
Procedures.Description,
Procedures.DayToDayLevel AS ''Maxmimum Training Level'',
Procedures.DayToDayLevel AS ''Training level for Day to Day Usage'', 
Users.Username,
UsersProcedures.LevelTrained FROM Procedures CROSS JOIN Users LEFT JOIN UsersProcedures ON UsersProcedures.Username = Users.Username AND Procedures.SeriesNum = UsersProcedures.SeriesNum AND Procedures.ProcNum = UsersProcedures.ProcNum) AS Procs
PIVOT(
MAX(LevelTrained)
FOR Procs.Username
IN('+@users+')) AS PivotTable'
execute(@query);