SQL动态数据透视表

时间:2017-01-23 13:16:55

标签: sql-server pivot

在制作动态数据透视表时,我正在努力解决错误

源数据

JobID | SalesForMonth | YearMonth
7734  |   400         | 2016-12
7734  |   350         | 2017-01
8540  |   444         | 2016-12
8540  |   300         | 2017-01

并以

为目标
JobID | 2016-12 | 2017-01
7734  |   400   |   350
8540  |   444   |   300

我尝试使用我在此处找到的查询来创建列标题。但必须承认我并不真正理解'For XML'行并在第6行得到语法错误

DECLARE 
@cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)
SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(YearMonth) 
                FROM v_JobSalesByMonth
        FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')

SELECT @query = 
'SELECT * FROM
(SELECT JobID, YearMonth, SalesForMonth
FROM v_JobSalesByMonth) X
PIVOT 
(
(JobID, SalesForMonth)
for [YearMonth] in (' + @cols + ')
) P'

我还想坚持使用jobID列的“总销售额”

非常感谢任何帮助

1 个答案:

答案 0 :(得分:0)

Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(YearMonth) From v_JobSalesByMonth  Order by 1 For XML Path('')),1,1,'') 
Select  @SQL = '
Select [JobID],[TotalSales],' + @SQL + '
From (
        Select JobID
              ,TotalSales = sum(SalesForMonth) over (Partition By JobID)
              ,YearMonth
              ,SalesForMonth
         From v_JobSalesByMonth A
     ) A
 Pivot (sum(SalesForMonth) For [YearMonth] in (' + @SQL + ') ) p'
Exec(@SQL);

返回

enter image description here

  

编辑 - 动态创建视图

由于您无法在视图中使用动态SQL,因此可以安排作业(每日或每月)删除并重新创建视图。

if object_id('vw_SalesByMonth','v') is not null
drop view vw_SalesByMonth;


Declare @SQL varchar(max) = Stuff((Select Distinct ',' + QuoteName(YearMonth) From Yourtable  Order by 1 For XML Path('')),1,1,'') 
Select  @SQL = '
Create View vw_SalesByMonth
AS

Select [JobID],[TotalSales],' + @SQL + '
From (
        Select JobID
              ,TotalSales = sum(SalesForMonth) over (Partition By JobID)
              ,YearMonth
              ,SalesForMonth
         From YourTable A
     ) A
 Pivot (sum(SalesForMonth) For [YearMonth] in (' + @SQL + ') ) p'
Exec(@SQL);

Select * from vw_SalesByMonth