For SQL Server 2005, 2008
The table and some data to test
CREATE TABLE CompetitorDetail ( ID int ,CompetitorID int ,oDate datetime ,Price decimal(19, 4) ) INSERT INTO CompetitorDetail ( ID, CompetitorID, oDate, Price ) SELECT 1, 1, '2010-01-01', 100.0 UNION SELECT 2, 1, '2010-01-02', 110.0 UNION SELECT 3, 1, '2010-01-03', 99.0 UNION SELECT 4, 2, '2010-01-01', 102.2 UNION SELECT 5, 2, '2010-01-02', 112.2 UNION SELECT 6, 2, '2010-01-03', 99.2 UNION SELECT 7, 3, '2010-01-01', 100.3 UNION SELECT 8, 3, '2010-01-02', 110.3 UNION SELECT 9, 3, '2010-01-03', 99.3 ;
Start of the period and number of days
/* First day of the peroid */ DECLARE @StartDate datetime ,@NumberOfDays int SET @StartDate = '2010-01-01' SET @NumberOfDays = 31
Dynamic columns = dynamic sql
/* Table to compose dynamic query */ DECLARE @qw TABLE ( id int IDENTITY(1, 1) ,txt nvarchar(500) ) /* Start composing dynamic query */ INSERT INTO @qw ( txt ) VALUES ( 'SELECT' ) INSERT INTO @qw ( txt ) VALUES ( 'CompetitorID' )
Continue composing the dynamic query
/* Helpers */ DECLARE @dte datetime ,@str varchar(10) ,@i int /* Compose dynamic query */ SET @i = 0 WHILE @i < @NumberOfDays BEGIN SET @dte = DATEADD(d, @i, @StartDate) SET @str = CONVERT(varchar(10), @dte, 121) INSERT INTO @qw ( txt ) SELECT ',MAX(CASE oDate WHEN ''' + @str + ''' THEN Price ELSE NULL END) AS [' + @str + ']' SET @i = @i + 1 END /* Finish the dynamic query */ INSERT INTO @qw (txt) VALUES ( 'FROM CompetitorDetail' ) INSERT INTO @qw (txt) VALUES ( 'GROUP BY CompetitorID' ) INSERT INTO @qw (txt) VALUES ( 'ORDER BY CompetitorID' )
Concatenate into a variable and execute
/* Create a variable with dynamic sql*/ DECLARE @exe nvarchar(4000) SET @exe='' SELECT @exe = @exe + txt + ' ' FROM @qw ORDER BY id /* execute dynamic sql */ EXEC sp_executesql @exe
Returns
CompetitorID 2010-01-01 2010-01-02 2010-01-03 2010-01-04 ... 2010-01-31 ------------ ---------- ---------- ---------- ---------- ... ---------- 1 100.0000 110.0000 99.0000 NULL ... NULL 2 102.2000 112.2000 99.2000 NULL ... NULL 3 100.3000 110.3000 99.3000 NULL ... NULL