I need help to switch columns with rows in SQL. Need to turn this:
+------------+------------+-------------+------+
| 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 | |
|... | | | |
+------------+------------+-------------+------+
into this:
+------------+------------+------------+------------+------------+-----+
| 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 | |
+------------+------------+------------+------------+------------+-----+
Can someone help me? Should I use PIVOT
?
EDIT: I've tried using some suggestions like PIVOT
and UNPIVOT
, but I could not achieve the expected result.
I've tried:
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
However with the above query I only managed to get some of what I need,
+------------+------------+------------+------------+------------+-----+
| 01-01-2017 | 02-01-2017 | 03-01-2017 | 04-01-2017 | 05-01-2017 | ... |
+------------+------------+------------+------------+------------+-----+
| 100 | 200 | 150 | 250 | 30 | |
+------------+------------+------------+------------+------------+-----+
I need to have production and consumption, all in the same query, but I can only get one of them.
Is it possible to put more than one column in PIVOT
? I've tried, but unsuccessfully.
You can achieve the desired output with dynamic sql, but be aware of performance and security problems (ie SQL injection) of this approach.
--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)
Result:
Now if you add a column and some more rows:
--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)
this is the result:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.