/*
Dynamic Crosstab transforming TEXT 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
3) perform transformation on text data (the original uses MONEY data type)
*/
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 VARCHAR(50)
)
INSERT INTO #Aggregates
(
RowText,
ColumnText,
CellData
)
------------------------------------
-- source query to be transformed --
------------------------------------
/*
i have picked an adventureworks table
as an example.
*/
select
GroupName,
row_number() over (partition by GroupName order by Name),
Name
from
HumanResources.Department
------------------------------------
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) + ' VARCHAR(50) NOT NULL DEFAULT '''''
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
Wednesday, 21 February 2007
Dynamic Crosstab transforming TEXT data from columns to rows
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment