REVISED Dynamic Crosstab Query
Here is a revised version of the crosstab query I submitted last week. This new version avoids the WHILE loop (which was used in my pervious version) and is thus COMPLETELY SET-ORIENTED for better performance.
/* Create and populate tables for testing */
CREATE TABLE employees
(empid INT PRIMARY KEY, empname VARCHAR(100))
GO
CREATE TABLE sales
(saleid INT PRIMARY KEY, empid INT FOREIGN KEY REFERENCES employees(empid), saledate DATETIME, saleamount MONEY)
GO
INSERT INTO employees
SELECT 1, 'joe' UNION SELECT 2, 'mary' UNION SELECT 3, 'bob'
GO
INSERT INTO sales
SELECT 1, 1, '01/10/2003', 10000
UNION
SELECT 2, 1, '01/20/2003', 5000
UNION
SELECT 3, 1, '02/10/2003', 10000
UNION
SELECT 4, 1, '03/10/2003', 20000
UNION
SELECT 5, 1, '05/10/2003', 8000
UNION
SELECT 6, 2, '01/10/2003', 12000
UNION
SELECT 7, 2, '02/10/2003', 10000
UNION
SELECT 8, 2, '04/10/2003', 15000
UNION
SELECT 9, 3, '01/10/2003', 7000
UNION
SELECT 10, 3, '05/10/2003', 10000
UNION
SELECT 11, 3, '05/10/2003', 15000
GO
/* Code for creating crosstab */
DECLARE @sql VARCHAR(8000)
SELECT @sql =
ISNULL(@sql + ', ', 'SELECT e.empname, ') +
'SUM(CASE DATENAME(MONTH, s.saledate)' + CHAR(13) +
'WHEN ''' + salemonth + '''' + CHAR(13) +
'THEN saleamount' + CHAR(13) +
'ELSE 0 END) AS [Sales-' + salemonth + ']'
+ CHAR(13)
FROM
(
SELECT DISTINCT TOP 100 PERCENT
DATENAME(MONTH, saledate) AS salemonth,
MONTH(saledate) as monthno
FROM sales
ORDER BY monthno
) s
SET @sql = @sql + CHAR(13) +
'FROM employees e
JOIN sales s
ON e.empid = s.empid
GROUP BY e.empname'
--PRINT @sql --uncomment for debugging
EXEC(@sql)