benjamin.nelson06 (5/13/2008)
Very interesting as I have been working on doing a similar thing now for a few days. However I needed a Grand Total Column and a Grand Total Row for reporting purposes. I also did not know what the PivotValues would be therefore this all had to be done with dynamic SQL. I too created a temporary table in order to store the data before I pivoted the data. Here is how I did it (Please excuse the smiley's as they automatically were added. where you see a smily it's just a close paren.)--Get the Pivot Columns by querying the distinct [Month]& Year values from the query
Declare @PivotValues as VARCHAR(8000)
Declare @PivotSum as VARCHAR(8000)
Declare @PivotTotal as VARCHAR(8000)
Declare @PivotTypes as VARCHAR(8000)
Declare @MonthYear as VARCHAR(25)
Declare @EDATEMM as INT
Declare @Year as INT
--Loop over the @YearMonth CURSOR table to build our PivotField Values
DECLARE YearMonth_cursor CURSOR FOR
SELECT DISTINCT dbo.MonthMst.[Month] + '-' + CAST(Year([EDATE]) as varchar(4)), EDATEMM, Year([EDATE])
FROM dbo.MonthMst INNER JOIN
@MasterSubset AS MS ON dbo.MonthMst.cLngMonthCode = MS.EDATEMM
Order By Year([EDATE]), EDATEMM
OPEN YearMonth_cursor
FETCH NEXT FROM YearMonth_cursor
INTO @MonthYear, @EDATEMM, @Year
WHILE @@FETCH_STATUS = 0
BEGIN
--Build the PivotValues to be used in forming the Pivot Statement
If COALESCE(@PivotValues, '') = ''
SET @PivotValues = '[' + @MonthYear + ']'
ELSE
SET @PivotValues = @PivotValues + ',[' + @MonthYear + ']'
--Build the PivotTotal for use in forming the Grand Total Column
If COALESCE(@PivotTotal, '') = ''
SET @PivotTotal = 'COALESCE([' + @MonthYear + '],0)'
ELSE
SET @PivotTotal = @PivotTotal + ' + COALESCE([' + @MonthYear + '],0)'
--Build the PivotSum for use in forming the Grand Total Row
If COALESCE(@PivotSum, '') = ''
SET @PivotSum = 'SUM(COALESCE([' + @MonthYear + '],0))'
ELSE
SET @PivotSum = @PivotSum + ', SUM(COALESCE([' + @MonthYear + '],0))'
--Build the PivotTypes for use in declaring a Table Variable
If COALESCE(@PivotTypes, '') = ''
SET @PivotTypes = '[' + @MonthYear + '] INT NULL'
ELSE
SET @PivotTypes = @PivotTypes + ', [' + @MonthYear + '] INT NULL'
-- Get the next YearMonth.
FETCH NEXT FROM YearMonth_cursor
INTO @MonthYear, @EDATEMM, @Year
END
--Add the Grand Total Column to the PivotValues
--This keeps us from having to modify the Structure in order to add
--The Grand Total column
set @PivotValues = @PivotValues + ',[Grand Total]'
--We will need to SUM the Grand Total Column in order to build the last value Grand Total
--Row
set @PivotSum = @PivotSum + ', SUM([Grand Total])'
--Add the Grand Total column to our PivotTypes as this needs to be a column in our Table Variable
set @PivotTypes = @PivotTypes + ',[Grand Total] INT NULL'
CLOSE YearMonth_cursor
DEALLOCATE YearMonth_cursor
DECLARE @SQL as NVARCHAR(4000)
--Stuff our Data into a Temporary table
--to be used in the dynamic SQL below
Select [Month] + '-' + CAST([Year] as varchar(4)) AS MonthYear, GroupCol1, GroupCol2, GroupCol3, AggregatCol
INTO #PivotData
from
(Select Month, Year, GroupCol1, GroupCol2, GroupCol3, AggregatCol From DataTable) as DT
--Now here was the tricky part. Since I didn't know what my pivot columns would be I needed
--to build dynamic SQL however I couldn't figure out how to get the data to return properly. So
--I basically created a dynamic stored proc without actually creating a stored proc.
SET @SQL = 'DECLARE @PivotTable1 TABLE( GroupCol1 varchar(50) NOT NULL,
GroupCol2 varchar(20) NOT NULL,
GroupCol3 varchar(20) NOT NULL,
' + @PivotTypes + ');
INSERT INTO @PivotTable1 (GroupCol1, GroupCol2, GroupCol3, ' + @PivotValues + ' )
Select GroupCol1, GroupCol2, GroupCol3, ' + @PivotValues + '
FROM
(Select GroupCol1, GroupCol2, GroupCol3, ' + @PivotValues + '
FROM
(
Select MonthYear,GroupCol1,GroupCol2,
GroupCol3, AggregateCol
from #PivotData
) As Source
PIVOT
(
SUM(Source.AggregateCol)
FOR MONTHYEAR IN (' + @PivotValues + ')
) As PivotTable) As PT;
Update @PivotTable1 Set [Grand Total] = ' + @PivotTotal +
'; Insert Into @PivotTable1 (GroupCol1, GroupCol2, GroupCol3, ' + @PivotValues + ')
Select ''Grand Total'', '''', '''', ' + @PivotSum + ' From @PivotTable1;
Select * From @PivotTable1;'
Exec sp_executesql @sql
Drop Table #PivotData
And here are the results:
GroupCol1 GroupCol2 GroupCol3 January-2007 February-2007 Grand Total
-------------------------------------------------------------------------------------------------
GroupValue1 Group2Value1 Group3Value1 391 356 747
GroupValue2 Group2Value2 Group3Value1 356 419 775
GroupValue3 Group2Value3 Group3Value1 181 181 362
Grand Total 928 956 1884
Post the table CREATE statements and some sample data according to the URL in my signature... you'll be surprised at how many will give you a working code example in return... 😉
--Jeff Moden
Change is inevitable... Change for the better is not.