2015-04-22 4 views
0

Я хочу, чтобы отобразить расход определенного месяца, используя поворотную table.here я применил мой код для реферальногоСводная таблица в SQL Server для моего отображения общей стоимости

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) 

DECLARE @ColumnName AS NVARCHAR(MAX) 

SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(years) 
FROM (SELECT DISTINCT years FROM pivots) AS years 

SET @DynamicPivotQuery = N'SELECT DISTINCT months, ' + @ColumnName + FROM pivots 
     PIVOT(SUM(expense) FOR years IN (' + @ColumnName + ')) AS PVTTable' 

EXEC sp_executesql @DynamicPivotQuery 

Выхода выходит отображаюсь ниже

months 2014 2015 2016 
    febuary 200 NULL NULL 
    january NULL 100 NULL 
    january 500 NULL NULL 
    march NULL NULL 300 

выход, который я хочу январе значение не должно повторяться twice.it следует обновить значение в нуль place.It не должно создавать еще один столбец значений

+3

MySQL? Вы уверены, что? –

+1

И SQL Server. – sqluser

+0

Можете ли вы добавить некоторые примеры данных для таблицы, которую вы используете (опорные точки)? – sqluser

ответ

2

Я думаю, что у вас есть другой столбец (или больше) в таблице, которые вы не выбираете, который меняется в течение одного месяца. Оператор PIVOT будет группироваться по всем доступным столбцам, а не только по тем, которые вы выберете на выходе.

Возьмем следующую таблицу, например:

CREATE TABLE #Pivots (Months VARCHAR(100), Years INT, expense INT, Col INT); 
INSERT #Pivots 
VALUES 
    ('febuary', 2014, 200, 1), 
    ('january', 2014, 500, 1), 
    ('january', 2015, 100, 2), 
    ('march', 2016, 300, 1); 

При запуске:

SELECT * 
FROM #Pivots AS p 
     PIVOT 
     ( SUM(expense) 
      FOR Years IN ([2014], [2015], [2016]) 
     ) AS pvt 
ORDER BY months; 

Вы можете видеть более ясно, почему есть два ряда для january (1 для каждого значения в Col):

Months Col 2014 2015 2016 
------------------------------ 
febuary 1 200  NULL NULL 
january 1 500  NULL NULL 
january 2 NULL 100  NULL 
march 1 NULL NULL 300 

Потому что Col is fe d в PIVOT, он является частью неявного GROUP BY, в вашем случае вы не выбираете никаких других столбцов, поэтому эта причина искажается.

Обойти это использовать подзапрос только выбрать соответствующие столбцы:

SELECT * 
FROM ( SELECT months, years, expense 
      FROM #Pivots 
     ) AS p 
     PIVOT 
     ( SUM(expense) 
      FOR Years IN ([2014], [2015], [2016]) 
     ) AS pvt 
ORDER BY months; 

Что дает ожидаемые результаты:

months 2014 2015 2016 
------------------------------ 
febuary 200  NULL NULL 
january 500  100  NULL 
march NULL NULL 300 

Таким образом, ваш полный запрос будет:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX); 

DECLARE @ColumnName AS NVARCHAR(MAX); 

SELECT @ColumnName= ISNULL(@ColumnName + ',','') + QUOTENAME(years) 
FROM (SELECT DISTINCT years FROM pivots) AS years; 

SET @DynamicPivotQuery = N'SELECT DISTINCT months, ' + @ColumnName + 'FROM (SELECT months, years, expense FROM pivots) AS p 
     PIVOT(SUM(expense) FOR years IN (' + @ColumnName + ')) AS PVTTable'; 

EXEC sp_executesql @DynamicPivotQuery; 

DROP TABLE #Pivots; 

Для чего это стоит, самый быстрый и надежный способ создания столбцов на самом деле t о использовании расширений XML в SQL Server, а также DISTINCT в окончательном запросе является излишним, вы можете быть лучше использовать:

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX), 
     @ColumnName AS NVARCHAR(MAX); 

SET @ColumnName = STUFF(( SELECT ',' + QUOTENAME(years) 
          FROM pivots 
          GROUP BY years 
          ORDER BY years 
          FOR XML PATH(''), TYPE 
         ).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

SET @DynamicPivotQuery = 'SELECT months, ' + @ColumnName + ' 
         FROM (SELECT years, months, expense FROM pivots) AS p 
          PIVOT (SUM(expense) FOR years IN (' + @ColumnName + ')) AS pvt' 

EXECUTE sp_executesql @DynamicPivotQuery; 
Смежные вопросы