Вы можете достичь желаемого результата с помощью динамического sql, но помните о проблемах производительности и безопасности (например, SQL-инъекция) этого подхода.
--create test table
CREATE TABLE dbo.Test (
[Date] date
, Production int
, Consumption int
)
--populate test table with values
insert into dbo.Test
values
('2017-01-01', 100, 1925)
,('2017-01-02', 200, 2005)
,('2017-01-03', 150, 1998)
,('2017-01-04', 250, 2200)
,('2017-01-05', 30, 130)
--table variable that will hold the names of all columns to pivot
declare @columNames table (ColumnId int identity (1,1), ColumnName varchar(255))
--variable that will hold the total number of columns to pivot
declare @columnCount int
--variable that will be used to run through the columns to pivot
declare @counter int = 1
--this variable holds all column names
declare @headers nvarchar(max) = ''
--this variable contains the TSQL dinamically generated
declare @sql nvarchar(max) = ''
--populate list of columns to pivot
insert into @columNames
select COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where
TABLE_NAME = 'test'
and TABLE_SCHEMA = 'dbo'
and COLUMN_NAME <>'date'
--populate column total counter
select @columnCount = count(*) from @columNames
--populate list of headers of the result table
select @headers = @headers + ', ' + quotename([Date])
from dbo.Test
set @headers = right(@headers, len(@headers) - 2)
--run through the table containing the columns names and generate the dynamic sql query
while @counter <= @columnCount
begin
select @sql = @sql + ' select piv.* from (select [Date], '
+ quotename(ColumnName) + ' from dbo.Test) p pivot (max('
+ quotename(ColumnName) + ') for [Date] in ('
+ @headers + ') ) piv '
from @columNames where ColumnId = @counter
--add union all except when we are concatenating the last pivot statement
if @counter < @columnCount
set @sql = @sql + ' union all'
--increment counter
set @counter = @counter + 1
end
--execute the dynamic query
exec (@sql)
Результат:
Теперь, если вы добавите столбец и еще несколько строк:
--create test table
CREATE TABLE [dbo].[Test] (
[Date] date
, Production int
, Consumption int
, NewColumn int
)
--populate test table with values
insert into [dbo].[Test]
values
('2017-01-01', 100, 1925 , 10)
,('2017-01-02', 200, 2005, 20)
,('2017-01-03', 150, 1998, 30)
,('2017-01-04', 250, 2200, 40)
,('2017-01-05', 30, 130 , 50)
,('2017-01-06', 30, 130 , 60)
,('2017-01-07', 30, 130 , 70)
это будет результат: