T-SQL 动态枢轴

T-SQL dynamic pivots

我正在尝试使用动态列名生成数据透视表 table,但失败得很惨。

我的 table 具有以下结构:

id, int() PKEY
prod_no, VARCHAR(20)
f_month, INT
f_year, INT
f_value, INT

示例数据如下所示

-------------------
AB1234|1|2016|15698
-------------------
AB1234|2|2016|25438
-------------------
AB1234|3|2016|53323
-------------------
AB1234|1|2017|34535
-------------------
AB1234|2|2017|66244
-------------------
AB1234|3|2017|54534
-------------------
CD9876|1|2016|43278
-------------------
CD9876|2|2016|11245
-------------------
CD9876|3|2016|82432
-------------------
CD9876|1|2017|93563
-------------------
CD9876|2|2017|89356
-------------------
CD9876|3|2017|45724
-------------------

我想要的结果是这样的:

prod_no|1-2016|2-2016|3-2016|1-2017|2-2017|3-2017|
--------------------------------------------------
AB1234 |15698 |25438 |53323 |34535 |66244 |54534 |
--------------------------------------------------
CD9876 |43278 |11245 |82432 |93563 |89356 |45724 |

所以列为 prod_no,后面是 f_month-f_year 的动态列 一个数据作为产品编号和值对应于该列中的月份。

我尝试了一些来自网络的动态枢轴示例,但到目前为止还没有成功实现它

试试这个:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);



SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(varchar,c.f_month)+'-'+convert(varchar,c.f_year)) 
            FROM dynpi c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
print @cols

set @query = 'SELECT  prod_no,' + @cols + ' from 
            (
                select prod_no, f_value,convert(varchar,f_month)+''-''+convert(varchar,f_year) as dyn

                from dynpi
           ) x
            pivot 
            (
                 max(f_value)
                for dyn in (' + @cols + ')
            ) p '


execute(@query)

结果是:

*---------*---------*-------*-------*-------*-------*------*
|prod_no  |1-2016   |1-2017 |2-2016 |2-2017 |3-2016 |3-2017| 
*---------*---------*-------*-------*-------*-------*------*
|AB1234   |15698    |34535  |25438  |66244  |53323  |54534 |  
*---------*---------*-------*-------*-------*-------*------*   
|CD9876   |43278    |93563  |11245  |89356  |82432  |45724 |     
*---------*---------*-------*-------*-------*-------*------*

这将保持所需的列顺序

例子

Declare @SQL varchar(max) = '
Select *
 From (
        Select prod_no
              ,item  = concat(f_year,''-'',f_month)
              ,value = f_value
         From  YourTable
      ) A
 Pivot (sum([value]) For [Item] in (' + Stuff((Select ','+QuoteName(concat(f_year,'-',f_month)) 
                                               From (Select Distinct Top 100 f_year,f_month From YourTable Order By f_Year,f_month ) A
                                               For XML Path('')),1,1,'')  + ') ) p'
Exec(@SQL)
--Print @SQL

Returns