2017-01-23 3 views
0

я борюсь с ошибкой, делая Динамичная сводной таблицыSQL Dynamic сводную таблицу

Данные источника

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 

и я попытался для использования запроса, который я нашел здесь, для создания заголовков столбцов. Но должен признать, что я не очень понимаю «Для 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

Любая помощь будет высоко ценится

+0

У вас есть ошибка в вашем стержне. Вам нужно изменить '(JobID, SalesForMonth)' на 'sum (SalesForMonth)'. Вот демон (http://data.stackexchange.com/stackoverflow/query/618823). Затем, если вы хотите получить общий результат JobId, вы можете использовать 'sum (SalesForMonth) over ...()' - вот еще одна демонстрация - http://data.stackexchange.com/stackoverflow/query/618826 – Taryn

+0

SQL Server 2016 добавил 'STRING_AGG' функция –

ответ

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

EDIT - Динамически Создать вид

Поскольку вы не можете иметь динамический 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 
+0

Ухать прокомментировать? –

+0

Привет, Джон, я абсолютно уверен, что голосование связано с тем фактом, что этот вопрос ответил несколько раз раньше, и люди стараются сохранить СО-порядок ... Я поставил ответ только потому, что думал, что есть очевидная ошибка, но я был слепым olm :-) Во всяком случае, я удалю шахту, поскольку она позже вашей ... – Shnugo

+0

Большое спасибо, именно то, что мне было нужно. Тем не менее, вы все еще не уверены в цели бита пути XML? – PaulStephen

Смежные вопросы