Tuesday, November 15, 2005

Dynamic Crosstab in SQL Server

create PROC sp_CrossTab
@table AS sysname, -- Table to crosstab
@onrows AS nvarchar(500), -- Grouping key values (on rows)
@onrowsalias AS sysname = NULL, -- Alias for grouping column
@oncols AS nvarchar(1000), -- Destination columns (on columns)
@sumcol AS sysname = NULL, -- Data cells
@whereclause as nvarchar(500)= NULL -- where clause
AS
DECLARE
@sql AS varchar(8000),
@NEWLINE AS char(1)

SET @NEWLINE = CHAR(10)

-- step 1: beginning of SQL string
SET @sql =
'SELECT' + @NEWLINE +
' ' + @onrows +
CASE
WHEN @onrowsalias IS NOT NULL THEN ' AS ' + @onrowsalias
ELSE ''
END


CREATE TABLE #keys(keyvalue nvarchar(100) NOT NULL PRIMARY KEY)

DECLARE @keyssql AS varchar(1000)
SET @keyssql =
'INSERT INTO #keys ' +
'SELECT DISTINCT CAST(' + @oncols + ' AS nvarchar(100)) ' +
'FROM ' + @table

print @keyssql
EXEC (@keyssql)


DECLARE @key AS nvarchar(100)
SELECT @key = MIN(keyvalue) FROM #keys

WHILE @key IS NOT NULL
BEGIN
SET @sql = @sql + ',' + @NEWLINE +
' SUM(CASE CAST(' + @oncols +
' AS nvarchar(100))' + @NEWLINE +
' WHEN N''' + @key +
''' THEN ' + CASE
WHEN @sumcol IS NULL THEN '1'
ELSE @sumcol
END + @NEWLINE +
' ELSE 0' + @NEWLINE +
' END) AS [' + @key+ ']'

SELECT @key = MIN(keyvalue) FROM #keys
WHERE keyvalue > @key
END

SET @sql = @sql + @NEWLINE +
'FROM ' + @table + @NEWLINE
if @whereclause is not null
SET @sql = @sql+ 'WHERE ' + @whereclause + ' '+ @NEWLINE
SET @sql = @sql+ 'GROUP BY ' + @onrows + @NEWLINE
SET @sql = @sql+ 'ORDER BY ' + @onrows

PRINT @sql + @NEWLINE -- For debug
EXEC (@sql)


---Reference SQL Magazine
----------------------------------------
Eg:

Use Northwind
go
EXEC sp_CrossTab
@table = 'Orders',
@onrows = 'MONTH(OrderDate)',
@onrowsalias = 'OrderMonth',
@oncols = 'YEAR(OrderDate)'


USE pubs
go
EXEC sp_CrossTab
@table = 'sales',
@onrows = 'stor_id',
@oncols = 'YEAR(ord_date)',
@sumcol = 'qty'

0 Comments:

Post a Comment

<< Home

 
Google
 
Web mallier.blogspot.com