Search code examples
t-sqldynamic-pivot

Dynamic PIVOT two columns prefix


Database: Microsoft SQL Server 2012

I have one table that contains the computers and the software installed. Now, one computer can have 30+ software installed but there are probably 100+ different software on the infrastructure.

This is a representation of the table

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

I'm looking for a result that would look like this

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

I've been looking into dynamic PIVOT but I'm still new with SQL.

Thank you for the help


Solution

  • There are countless examples of dynamic pivots here, however, I understand sometimes we all need a little jump-start.

    Example

    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
    

    If it helps, the generated SQL looks like this:

    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