我需要帮助在SQL中使用行切换列。需要转此:
+------------+------------+-------------+------+
| Date | Production | Consumption | .... |
+------------+------------+-------------+------+
| 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 | |
|... | | | |
+------------+------------+-------------+------+
进入这个:
+------------+------------+------------+------------+------------+-----+
| 01-01-2017 | 02-01-2017 | 03-01-2017 | 04-01-2017 | 05-01-2017 | ... |
+------------+------------+------------+------------+------------+-----+
| 100 | 200 | 150 | 250 | 30 | |
| 1925 | 2005 | 1998 | 2200 | 130 | |
+------------+------------+------------+------------+------------+-----+
有人能帮我吗?我应该使用PIVOT
吗?
编辑:我已经尝试使用像PIVOT
和UNPIVOT
这样的建议,但我无法达到预期的结果。
我试过了:
SELECT *
FROM (
SELECT date, Consumption
FROM Energy
where date < '2017-02-01'
) r
pivot (sum(Consumption) for date in ([2017-01-01],[2017-01-02],[2017-01-03]....)) c
order by 1
但是通过上面的查询我只能设法获得我需要的一些东西,
+------------+------------+------------+------------+------------+-----+
| 01-01-2017 | 02-01-2017 | 03-01-2017 | 04-01-2017 | 05-01-2017 | ... |
+------------+------------+------------+------------+------------+-----+
| 100 | 200 | 150 | 250 | 30 | |
+------------+------------+------------+------------+------------+-----+
我需要生产和消费,所有都在同一个查询中,但我只能得到其中一个。
是否可以在PIVOT
中放置多个列?我试过了,但没有成功。
您可以使用动态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)
这是结果: