[英]How to convert SQL Server columns into rows?
I need help to switch columns with rows in SQL.我需要帮助在 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
?我应该使用
PIVOT
吗?
EDIT: I've tried using some suggestions like PIVOT
and UNPIVOT
, but I could not achieve the expected result.编辑:我尝试使用一些建议,如
PIVOT
和UNPIVOT
,但我无法达到预期的结果。
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
?是否可以在
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.您可以使用动态 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)
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:这是结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.