如何使用SQL Server 2014动态取消透视列

时间:2019-02-07 16:43:30

标签: sql-server unpivot

SQL表中的数据是

Cust_Name   Prd_Name    1/1/2019    2/1/2019    3/1/2019
John        Mobile        18.5        45.7       66.9
Scott       Laptop         9.5        3.7         0

我要取消透视[1/1/2019],[2/1/2019],[3/1/2019]列,并希望结果如下所示

Cust_Name   Prd_Name     Sales_Month    Value
John        Mobile        1/1/2019      18.5
John        Mobile        2/1/2019      45.7
John        Mobile        3/1/2019      66.9
Scott       Laptop        1/1/2019      9.5
Scott       Laptop        2/1/2019      3.7
Scott       Laptop        3/1/2019      0

我该怎么做?另外,我要取消透视的此类列的数量是动态的,因此它以1/1/2019,2/1/2019开头,但可以进行到12/1/2019

1 个答案:

答案 0 :(得分:3)

这是一个选项,可以动态取消数据透视,而无需实际使用动态SQL。

XML不喜欢以数字开头的商品名称,因此我们必须进行一些清理...因此replace(replace(replace(...)))

示例

Select A.Cust_Name
      ,A.Prd_Name
      ,Sales_Month = replace(
                     replace(
                     replace(C.Item,'_x003','')
                     ,'__x002F_','/')
                     ,'_x002F_','/')
      ,C.Value 
 From  YourTable A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Item  = xAttr.value('local-name(.)', 'varchar(100)')
                      ,Value = xAttr.value('.','varchar(max)')
                 From  XMLData.nodes('//@*') xNode(xAttr)
                 Where xAttr.value('local-name(.)','varchar(100)') not in ('Cust_Name','Prd_Name')
             ) C

返回

Cust_Name   Prd_Name    Sales_Month Value
John        Mobile      1/1/2019    18.5
John        Mobile      2/1/2019    45.7
John        Mobile      3/1/2019    66.9
Scott       Laptop      1/1/2019    9.5
Scott       Laptop      2/1/2019    3.7
Scott       Laptop      3/1/2019    0.0