如何将多列 UNPIVOT 成两列以上?
How to UNPIVOT multiple columns into more than two columns?
我在 SybaseASE 15.X 数据库中有数据,我正在尝试查询整齐的数据。数据在 Sybase table 中的结构如下:
| Name | Foo_A | Foo_B | Foo_C | Bar_A | Bar_B | Bar_C |
--------------------------------------------------------
| abcd | 16 | 32 | 14 | 52 | 41 | 17 |
| ... | ... | ... | ... | ... | ... | ... |
我希望以如下方式查询数据:
| Name | Class | FooVal | BarVal |
----------------------------------
| abcd | A | 16 | 52 |
| abcd | B | 32 | 41 |
| abcd | C | 14 | 17 |
| ... | ... | ... | ... |
现在,我已经知道并正在使用 UNION ALL
,但是 什么是更简洁和直接的方式 来完成看似简单的事情UNPIVOT
?
就我在本网站、MSDN 文档、SAP 文档和 SQL 参考资料中阅读的内容而言,UNPIVOT
仅适用于两列输出。
如果有更多有用的信息,请告诉我。谢谢!
使用UNION ALL
:
select t.*
from (select Name, 'A' as Class, Foo_A as FooVal, Bar_A as BarVal
from table
union all
select Name, 'B', Foo_B, Bar_B
from table
union all
select Name, 'C', Foo_C, Bar_C
from table
) t
order by name;
Sybase(现在是 SAP)ASE 没有 unpivot
功能(您可能已经知道),并且不支持向量函数(可以提供一对多的行拆分操作) .
除了 Yogesh 的 union all
解决方案之外,您可能还想查看具有 3 行伪 table 的交叉连接(笛卡尔积)的性能(假设您只有 3 类), 如:
-- setup
create table mytable(Name varchar(10), Foo_A int, Foo_B int, Foo_C int, Bar_A int, Bar_B int, Bar_C int)
go
insert mytable values ('abcd',16,32,14,52,41,17)
go
-- main query
select m.Name,
p.Class,
case when p.Class = 'A' then m.Foo_A
when p.Class = 'B' then m.Foo_B
when p.Class = 'C' then m.Foo_C
end as FooVal,
case when p.Class = 'A' then m.Bar_A
when p.Class = 'B' then m.Bar_B
when p.Class = 'C' then m.Bar_C
end as BarVal
from mytable m,
(select 'A' as Class
union all
select 'B'
union all
select 'C') p
order by m.Name, p.Class
go
Name Class FooVal BarVal
---------- ----- ----------- -----------
abcd A 16 52
abcd B 32 41
abcd C 14 17
要了解这是如何工作的,运行 下面查看连接生成的结果集,然后应用 case
逻辑查看最终行的生成方式:
select p.Class, m.*
from mytable m,
(select 'A' as Class
union all
select 'B'
union all
select 'C') p
order by m.Name, p.Class
go
我在 SybaseASE 15.X 数据库中有数据,我正在尝试查询整齐的数据。数据在 Sybase table 中的结构如下:
| Name | Foo_A | Foo_B | Foo_C | Bar_A | Bar_B | Bar_C |
--------------------------------------------------------
| abcd | 16 | 32 | 14 | 52 | 41 | 17 |
| ... | ... | ... | ... | ... | ... | ... |
我希望以如下方式查询数据:
| Name | Class | FooVal | BarVal |
----------------------------------
| abcd | A | 16 | 52 |
| abcd | B | 32 | 41 |
| abcd | C | 14 | 17 |
| ... | ... | ... | ... |
现在,我已经知道并正在使用 UNION ALL
,但是 什么是更简洁和直接的方式 来完成看似简单的事情UNPIVOT
?
就我在本网站、MSDN 文档、SAP 文档和 SQL 参考资料中阅读的内容而言,UNPIVOT
仅适用于两列输出。
如果有更多有用的信息,请告诉我。谢谢!
使用UNION ALL
:
select t.*
from (select Name, 'A' as Class, Foo_A as FooVal, Bar_A as BarVal
from table
union all
select Name, 'B', Foo_B, Bar_B
from table
union all
select Name, 'C', Foo_C, Bar_C
from table
) t
order by name;
Sybase(现在是 SAP)ASE 没有 unpivot
功能(您可能已经知道),并且不支持向量函数(可以提供一对多的行拆分操作) .
除了 Yogesh 的 union all
解决方案之外,您可能还想查看具有 3 行伪 table 的交叉连接(笛卡尔积)的性能(假设您只有 3 类), 如:
-- setup
create table mytable(Name varchar(10), Foo_A int, Foo_B int, Foo_C int, Bar_A int, Bar_B int, Bar_C int)
go
insert mytable values ('abcd',16,32,14,52,41,17)
go
-- main query
select m.Name,
p.Class,
case when p.Class = 'A' then m.Foo_A
when p.Class = 'B' then m.Foo_B
when p.Class = 'C' then m.Foo_C
end as FooVal,
case when p.Class = 'A' then m.Bar_A
when p.Class = 'B' then m.Bar_B
when p.Class = 'C' then m.Bar_C
end as BarVal
from mytable m,
(select 'A' as Class
union all
select 'B'
union all
select 'C') p
order by m.Name, p.Class
go
Name Class FooVal BarVal
---------- ----- ----------- -----------
abcd A 16 52
abcd B 32 41
abcd C 14 17
要了解这是如何工作的,运行 下面查看连接生成的结果集,然后应用 case
逻辑查看最终行的生成方式:
select p.Class, m.*
from mytable m,
(select 'A' as Class
union all
select 'B'
union all
select 'C') p
order by m.Name, p.Class
go