/*
Dynamic Crosstab transforming MONEY data from columns to rows
based on sql server central example, but modified to
1) remove error on table index hints
2) drop temporary objects first
*/
Use AdventureWorks
go
if object_id('tempdb..#Aggregates') is not null
begin
drop table #Aggregates
end
if object_id('tempdb..#Columns') is not null
begin
drop table #Columns
end
if object_id('tempdb..#Rows') is not null
begin
drop table #Rows
end
CREATE TABLE #Aggregates
(
RowText VARCHAR(50),
ColumnText VARCHAR(50),
CellData MONEY
)
INSERT INTO #Aggregates
(
RowText,
ColumnText,
CellData
)
------------------------------------
-- source query to be transformed --
------------------------------------
/*
i have picked an adventureworks table
as an example.
*/
select
LastName + ' , ' + FirstName,
row_number() over (partition by eph.EmployeeID order by LastName + ' , ' + FirstName),
Rate
from
HumanResources.EmployeePayHistory eph
inner join
HumanResources.Employee e
on e.EmployeeID = eph.EmployeeID
inner join
Person.Contact c
on e.ContactID = c.ContactID
------------------------------------
CREATE UNIQUE INDEX IX_Aggregates ON #Aggregates (RowText, ColumnText, CellData)
CREATE TABLE #Columns
(
ColumnIndex INT IDENTITY (0, 1),
ColumnText VARCHAR(50)
)
INSERT INTO #Columns
(
ColumnText
)
SELECT DISTINCT ColumnText
FROM #Aggregates WITH (INDEX(IX_Aggregates), NOLOCK)
ORDER BY ColumnText
CREATE UNIQUE INDEX IX_Columns ON #Columns (ColumnIndex, ColumnText)
CREATE TABLE #Rows
(
RowText VARCHAR(50)
)
INSERT INTO #Rows
(
RowText
)
SELECT DISTINCT RowText
FROM #Aggregates WITH (INDEX(IX_Aggregates), NOLOCK)
CREATE UNIQUE INDEX IX_Rows ON #Rows (RowText)
DECLARE @ColumnIndex INT,
@MaxColumnIndex INT,
@ColumnText VARCHAR(50),
@SQL VARCHAR(1000)
SELECT @ColumnIndex = 0,
@MaxColumnIndex = MAX(ColumnIndex)
FROM #Columns
WHILE @ColumnIndex <= @MaxColumnIndex
BEGIN
SELECT @ColumnText = ColumnText
FROM #Columns
WHERE ColumnIndex = @ColumnIndex
SELECT @SQL = 'ALTER TABLE #Rows ADD ' + QUOTENAME(@ColumnText) + ' INT NULL DEFAULT 0'
EXEC (@SQL)
SELECT @SQL = 'UPDATE #Rows SET ' + QUOTENAME(@ColumnText) + ' = #Aggregates.CellData
FROM #Aggregates WITH (INDEX(IX_Aggregates), NOLOCK)
, #Columns WITH (INDEX(IX_Columns), NOLOCK)
WHERE #Rows.RowText = #Aggregates.RowText
AND #Columns.ColumnText = #Aggregates.ColumnText
AND #Columns.ColumnIndex = ' + CAST(@ColumnIndex AS VARCHAR(12))
EXEC (@SQL)
SELECT @ColumnIndex = @ColumnIndex + 1
END
DROP TABLE #Columns
DROP TABLE #Aggregates
SELECT #Rows.*
FROM #Rows
ORDER BY #Rows.RowText
DROP TABLE #Rows
Tuesday, 20 February 2007
Dynamic Crosstab transforming MONEY data from columns to rows
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment