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
我正在尝试使用动态列名生成数据透视表 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