如何在 SQL 中简单地切换列与行? 有没有简单的转置命令?
即转这个结果:
Paul | John | Tim | Eric
Red 1 5 1 3
Green 8 4 3 5
Blue 2 2 9 1
进入此:
Red | Green | Blue
Paul 1 8 2
John 5 4 2
Tim 1 3 9
Eric 3 5 1
PIVOT
对于这种情况来说似乎太复杂了。
最佳答案
有多种方法可以转换此数据。在您原来的帖子中,您指出 PIVOT
对于这种情况来说似乎太复杂,但使用 UNPIVOT
and PIVOT
可以非常轻松地应用它。 SQL Server 中的函数。
但是,如果您无权访问这些函数,可以使用 UNION ALL
复制到 UNPIVOT
,然后使用带有 CASE
的聚合函数code> 语句到 PIVOT
:
创建表:
CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);
INSERT INTO yourTable
([color], [Paul], [John], [Tim], [Eric])
VALUES
('Red', 1, 5, 1, 3),
('Green', 8, 4, 3, 5),
('Blue', 2, 2, 9, 1);
Union All、聚合和 CASE 版本:
select name,
sum(case when color = 'Red' then value else 0 end) Red,
sum(case when color = 'Green' then value else 0 end) Green,
sum(case when color = 'Blue' then value else 0 end) Blue
from
(
select color, Paul value, 'Paul' name
from yourTable
union all
select color, John value, 'John' name
from yourTable
union all
select color, Tim value, 'Tim' name
from yourTable
union all
select color, Eric value, 'Eric' name
from yourTable
) src
group by name
UNION ALL
通过将 Paul、John、Tim、Eric
列转换为单独的行来执行数据的 UNPIVOT
。然后,您将聚合函数 sum()
与 case
语句一起应用,以获取每种颜色
的新列。
逆透视和透视静态版本:
SQL Server 中的 UNPIVOT
和 PIVOT
函数使这种转换变得更加容易。如果您知道要转换的所有值,则可以将它们硬编码为静态版本以获得结果:
select name, [Red], [Green], [Blue]
from
(
select color, name, value
from yourtable
unpivot
(
value for name in (Paul, John, Tim, Eric)
) unpiv
) src
pivot
(
sum(value)
for color in ([Red], [Green], [Blue])
) piv
使用UNPIVOT
的内部查询执行与UNION ALL
相同的功能。它获取列列表并将其转换为行,然后PIVOT
执行最终转换为列。
动态枢轴版本:
如果您的列数未知(示例中为 Paul、John、Tim、Eric
),并且要转换的颜色数未知,您可以使用动态 sql 生成列表来UNPIVOT
,然后PIVOT
:
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 <> 'color'
for xml path('')), 1, 1, '')
select @colsPivot = STUFF((SELECT ','
+ quotename(color)
from yourtable t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select name, '+@colsPivot+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('+@colsUnpivot+')
) unpiv
) src
pivot
(
sum(value)
for color in ('+@colsPivot+')
) piv'
exec(@query)
动态版本先查询 yourtable
,然后查询 sys.columns
表,以生成要发送到 UNPIVOT
和 PIVOT 的项目列表
。然后将其添加到要执行的查询字符串中。动态版本的优点是,如果您有一个不断变化的颜色
和/或名称
列表,这将在运行时生成该列表。
所有三个查询将产生相同的结果:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |
关于sql - 在 SQL 中转置列和行的简单方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13372276/