What you are trying to do is called PIVOT . This can be done in two ways: either with a static bar, where you hard-code all the values ββfor the conversion, or dynamic points where the values ββwere determined at run time.
Static version (see SQL Fiddle with Demo ):
select * from ( select dt, field1, col, value from yourTable unpivot ( value for col in (col1, col2, col3) ) u )x1 pivot ( min(value) for dt in ([2012-07-02], [2012-07-03], [2012-07-04]) ) p
Dynamic Pivot (see SQL Fiddle with Demo ):
DECLARE @colsUnpivot AS NVARCHAR(MAX), @query AS NVARCHAR(MAX), @colsPivot as NVARCHAR(MAX) select @colsUnpivot = stuff((select ','+quotename(C.name) from sys.columns as C where C.object_id = object_id('yourTable') and C.name like 'col%' for xml path('')), 1, 1, '') select @colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(convert(char(10), dt, 120)) from yourTable FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT col, field1, ' + +@colsPivot + ' FROM ( select dt, field1, col, value from yourTable unpivot ( value for col in ('+ @colsUnpivot+') ) u )x1 pivot ( min(value) for dt in (' +@colsPivot +') ) p ' exec(@query)
A dynamic bar is a great option when you do not know the number of elements that need to be converted to columns. Both give the same results.
Change # 1 if you want the date columns to be in a specific order - desc, etc., you will use the following to get the dates (see SQL Fiddle with Demo ):
select @colsPivot = STUFF((SELECT ', ' + QUOTENAME(convert(char(10), dt, 120)) from yourTable group by dt ORDER by dt desc FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'')