如何逆透视三种类型的值(包括 headers 列)
How can I unpivot three types of values (including the column headers)
我的数据是这样的:
╔═════════╦═════════╦═════════╦══════════════╦══════════════╦══════════════╗
║ option1 ║ option2 ║ option3 ║ percent_opt1 ║ percent_opt2 ║ percent_opt3 ║
╠═════════╬═════════╬═════════╬══════════════╬══════════════╬══════════════╣
║ 10 ║ 4 ║ 1 ║ 0.67 ║ 0.27 ║ 0.07 ║
╚═════════╩═════════╩═════════╩══════════════╩══════════════╩══════════════╝
因此,如果我想使前三列成为 headers 行值,然后其他列也成为更多行值,我该怎么做?
这就是我的意思:
╔═════════╦════════╦═════════════╗
║ options ║ values ║ percentages ║
╠═════════╬════════╬═════════════╣
║ option1 ║ 10 ║ 0.67 ║
╠═════════╬════════╬═════════════╣
║ option2 ║ 4 ║ 0.27 ║
╠═════════╬════════╬═════════════╣
║ option3 ║ 1 ║ 0.07 ║
╚═════════╩════════╩═════════════╝
这是我使用的代码:
declare @tbl as table (
option1 numeric(18,0),
option2 numeric(18,0),
option3 numeric(18,0),
per_opt1 numeric(18,2),
per_opt2 numeric(18,2),
per_opt3 numeric(18,2)
)
insert into @tbl
values (10,4,1,0.67,0.27,0.07)
;
select * from
(
select t.[option1],t.[option2],t.[option3]
from @tbl as t
) as srctbl
unpivot (
val for options in (option1,option2,option3)
) as unpiv
我不知道如何将最后三个百分比的列值设为行值,部分原因是我不能使用不同的数据类型,而且我不确定如何操作。
有什么建议吗?
使用横向连接 - 在 SQL 服务器中称为 apply
:
select x.*
from @tbl t
cross apply (values
('option1', t.option1, t.per_opt1),
('option2', t.option2, t.per_opt2),
('option3', t.option3, t.per_opt3)
) as x(options, vals, percentages)
options | vals | percentages
:------ | ---: | ----------:
option1 | 10 | 0.67
option2 | 4 | 0.27
option3 | 1 | 0.07
请注意 values
是一个 SQL 关键字 - 我在结果集中将该列重命名为 vals
。
使用apply
:
select v.*
from @tbl t cross apply
(values ('option1', option1, percent_opt1),
('option2', option2, percent_opt2),
('option3', option3, percent_opt3)
) v(option, value, percent_opt);
注意:values
是一个 SQL 关键字,所以我更改了中间列的名称。
在我看来,没有任何理由去学习unpivot
。它是定制功能——少量数据库的扩展——以 "okay" 的方式只做一件事。
另一方面,apply
支持 横向连接 ,这是标准的(即使语法因数据库而异)。它们非常强大,unpivoting 是开始了解它们的好方法。
我的数据是这样的:
╔═════════╦═════════╦═════════╦══════════════╦══════════════╦══════════════╗
║ option1 ║ option2 ║ option3 ║ percent_opt1 ║ percent_opt2 ║ percent_opt3 ║
╠═════════╬═════════╬═════════╬══════════════╬══════════════╬══════════════╣
║ 10 ║ 4 ║ 1 ║ 0.67 ║ 0.27 ║ 0.07 ║
╚═════════╩═════════╩═════════╩══════════════╩══════════════╩══════════════╝
因此,如果我想使前三列成为 headers 行值,然后其他列也成为更多行值,我该怎么做?
这就是我的意思:
╔═════════╦════════╦═════════════╗
║ options ║ values ║ percentages ║
╠═════════╬════════╬═════════════╣
║ option1 ║ 10 ║ 0.67 ║
╠═════════╬════════╬═════════════╣
║ option2 ║ 4 ║ 0.27 ║
╠═════════╬════════╬═════════════╣
║ option3 ║ 1 ║ 0.07 ║
╚═════════╩════════╩═════════════╝
这是我使用的代码:
declare @tbl as table (
option1 numeric(18,0),
option2 numeric(18,0),
option3 numeric(18,0),
per_opt1 numeric(18,2),
per_opt2 numeric(18,2),
per_opt3 numeric(18,2)
)
insert into @tbl
values (10,4,1,0.67,0.27,0.07)
;
select * from
(
select t.[option1],t.[option2],t.[option3]
from @tbl as t
) as srctbl
unpivot (
val for options in (option1,option2,option3)
) as unpiv
我不知道如何将最后三个百分比的列值设为行值,部分原因是我不能使用不同的数据类型,而且我不确定如何操作。
有什么建议吗?
使用横向连接 - 在 SQL 服务器中称为 apply
:
select x.*
from @tbl t
cross apply (values
('option1', t.option1, t.per_opt1),
('option2', t.option2, t.per_opt2),
('option3', t.option3, t.per_opt3)
) as x(options, vals, percentages)
options | vals | percentages :------ | ---: | ----------: option1 | 10 | 0.67 option2 | 4 | 0.27 option3 | 1 | 0.07
请注意 values
是一个 SQL 关键字 - 我在结果集中将该列重命名为 vals
。
使用apply
:
select v.*
from @tbl t cross apply
(values ('option1', option1, percent_opt1),
('option2', option2, percent_opt2),
('option3', option3, percent_opt3)
) v(option, value, percent_opt);
注意:values
是一个 SQL 关键字,所以我更改了中间列的名称。
在我看来,没有任何理由去学习unpivot
。它是定制功能——少量数据库的扩展——以 "okay" 的方式只做一件事。
另一方面,apply
支持 横向连接 ,这是标准的(即使语法因数据库而异)。它们非常强大,unpivoting 是开始了解它们的好方法。