动态 PIVOT 两列前缀

Dynamic PIVOT two columns prefix

数据库:Microsoft SQL Server 2012

我有一个 table,其中包含计算机和安装的软件。 现在,一台计算机可以安装 30 多个软件,但基础架构上可能有 100 多个不同的软件。

这是 table

的表示
Computer  | Software
--------------------
PC123     | Office
PC123     | Firefox
PC456     | Office
PC456     | Firefox
PC456     | CAD
PC789     | Firefox
PC789     | Outlook
...

我正在寻找如下所示的结果

Computer  | Software 1 | Software 2 | Software 3 
------------------------------------------------
PC123     | Firefox    | Office     | NULL
PC456     | CAD        | Firefox    | Office
PC789     | Firefox    | Outlook    | NULL
...

我一直在研究动态 PIVOT,但我对 SQL 还是个新手。

感谢您的帮助

这里有无数动态枢轴的例子,但是,我理解有时候我们都需要一点快速启动。

例子

Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(concat('Software ',Row_Number() over (Partition By Computer Order By Software))) From Yourtable  Order by 1 For XML Path('')),1,1,'') 
Select  @SQL = '
Select [Computer],' + @SQL + '
From (
       Select Computer
             ,Software
             ,Col      = concat(''Software '',Row_Number() over (Partition By Computer Order By Software))
       From YourTable
     ) A
Pivot (max([software]) For [Col] in (' + @SQL + ') ) p'
Exec(@SQL);

Returns

Computer    Software 1  Software 2  Software 3
PC123       Firefox     Office      NULL
PC456       CAD         Firefox     Office
PC789       Firefox     Outlook     NULL

如果有帮助,生成的 SQL 如下所示:

Select [Computer],[Software 1],[Software 2],[Software 3]
From (
       Select Computer
             ,Software
             ,Col      = concat('Software ',Row_Number() over (Partition By Computer Order By Software))
       From YourTable
     ) A
Pivot (max([software]) For [Col] in ([Software 1],[Software 2],[Software 3]) ) p

另一种方法是使用 stuff 函数并将所有软件放在一行中。 我的代码可能略有偏差。我很烂,无法测试。

Results should look like this:
Computer    Software
PC123       Firefox, CAD, Office        
PC456       Firefox


SELECT t.Computer, Software_String.Software
FROM (SELECT DISTINCT Computer FROM TABLE) t
OUTER APPLY (
SELECT REPLACE(STUFF((
            SELECT ', ' + w.Start_Date, 100) 
            FROM Computer w
            WHERE c.Computer_ID = w.Computer_ID
            FOR XML PATH('')
            ), 1, 2, ''), '  ', ' ') [Software]
        ) Software_String

或者您可以使用 case 语句代替数据透视表。我发现 pivot 编程很慢而且写起来很痛苦。