有几种方法可以转换这些数据。在您的原始帖子中,您表示这种情况下似乎使用
PIVOT
太过复杂,但是在 SQL Server 中,可以很容易地使用
UNPIVOT
和 PIVOT
函数进行应用。
然而,如果您无法访问这些函数,则可以使用
UNION ALL
进行复制到
UNPIVOT
,然后再使用聚合函数和
CASE
语句进行
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
请查看SQL Fiddle with Demo。
UNION ALL
通过将列Paul, John, Tim, Eric
转换为单独的行来执行数据的UNPIVOT
。然后,您可以使用case
语句应用聚合函数sum()
来获取每个color
的新列。
静态版本的Unpivot和Pivot:
在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
请参见 SQL Fiddle with Demo。
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)
请参见 SQL Fiddle with Demo。
动态版本查询了yourtable
和sys.columns
表,以生成要UNPIVOT
和PIVOT
的项目列表。然后将其添加到要执行的查询字符串中。动态版本的优点是,如果您有一个不断变化的colors
和/或names
列表,则会在运行时生成该列表。
所有三个查询都会产生相同的结果:
| NAME | RED | GREEN | BLUE |
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |