Search code examples
sqlsql-server-2008pivotunpivot

SQL Server 2008 pivoting table with unknown column name


I am having trouble to pivot the following

    FirstName    LastName
    ----------------------
    Talyor       Swift
    Bruno        Mars

to the following

    ColumnName    ColumnValue
    --------------------------
    FirstName     Talyor
    LastName      Swift
    FirstName     Bruno
    LastName      Mars

I don't have any clue how to start this without hardcoding it especially the way to retrieve the column name from the system.

**Column Name in the source table is not given


Solution

  • Here is a "dynamic" approach which is accomplished via XML.

    Clearly UNPIVOT would be more performant

    Example

    Select C.*
          ,ColumnOrder = D.ORDINAL_POSITION
     From  YourTable A
     Cross Apply (Select XMLData = cast((Select A.* for XML Raw) as xml) ) B
     Cross Apply (
                    Select Item   = attr.value('local-name(.)','varchar(100)')
                          ,Value  = attr.value('.','varchar(max)') 
                     From  B.XMLData.nodes('/row') as n(r)
                     Cross Apply n.r.nodes('./@*') AS B(attr)
                 ) C
     Join INFORMATION_SCHEMA.COLUMNS D on D.Table_Name='YourTable' and D.Column_Name=C.Item
    

    Returns

    Item        Value   ColumnOrder
    FirstName   Talyor  1
    LastName    Swift   2
    FirstName   Bruno   1
    LastName    Mars    2
    

    EDIT - Dynamic UnPivot

    Declare @SQL varchar(max) ='
    Select ColumnOrder = D.ORDINAL_POSITION
          ,Item
          ,Value
     From  YourTable
     UnPivot (Value for Item in ('+Stuff((Select ',' +QuoteName(Name) 
                                           From  sys.columns 
                                           Where objecT_id = OBJECT_ID('YourTable') 
                                           For XML Path ('')),1,1,'')
                                 +')) as UnPiv
     Join INFORMATION_SCHEMA.COLUMNS D on D.Table_Name=''YourTable'' and D.Column_Name=UnPiv.Item
    '
    --Print @SQL
    Exec(@SQL)