Sql 行到列数据
我的表名为Sql 行到列数据,sql,oracle,unpivot,Sql,Oracle,Unpivot,我的表名为AA。我有3列,即x,y,z . 它正好有一行 select * from aa; x y z 10 20 30 我想要像这样的输出 10 20 30 我使用了下面的查询 select x from AA union all select y from AA union all select z from AA ; 它正在提供所需的输出。但有人告诉我这是不可行的。你们谁能为我提供最好的解决方案。你们的问题很好: select x from AA union all sel
AA
。我有3列,即x,y,z
. 它正好有一行
select * from aa;
x y z
10 20 30
我想要像这样的输出
10
20
30
我使用了下面的查询
select x from AA union all select y from AA union all select z from AA ;
它正在提供所需的输出。但有人告诉我这是不可行的。你们谁能为我提供最好的解决方案。你们的问题很好:
select x from AA union all
select y from AA union all
select z from AA ;
更高效的版本要长一点:
select (case when n = 1 then x
when n = 2 then y
else z
end) as x
from (select 1 as n from dual union all select 2 union all select 3
) cross join
AA;
较新版本的Oracle支持横向联接和应用
。如果您正在使用,我建议您:
select d(x)
from aa cross apply
(select aa.x from dual union all
select aa.y from dual union all
select aa.z from dual
) d
您可以使用一个简单的
UNPIVOT
SELECT
col
FROM
aa UNPIVOT ( col
FOR val
IN ( x,
y,
z ) );
我想你的面试官可能希望你回答这个问题
您可以使用Oracle的
将产生结果
name value
---- -----
x 10
y 20
z 30
见:
它可以推广到更多的列吗?由于列的名称需要预先知道,所以不能自动考虑其他列,但当然,可以手动添加更多列。示例还包含除值列以外的其他列:
CREATE TABLE AA (
position NVARCHAR2(50),
x NUMBER(10),
y NUMBER(10),
z NUMBER(10),
t NUMBER(10)
);
INSERT INTO AA (position, x, y, z, t) VALUES ('pos 1', 10, 20, 30, 1);
INSERT INTO AA (position, x, y, z, t) VALUES ('pos 2', 11, 22, 33, 2);
INSERT INTO AA (position, x, y, z, t) VALUES ('pos 3', 34, 45, 56, 3);
您可以通过以下方式进行查询:
SELECT *
FROM AA
UNPIVOT (
value FOR coord IN (x AS 'x', y AS 'y', z AS 'z', t as 'time')
);
得到
POSITION COORD VALUE
-------- ----- -----
pos 1 x 10
pos 1 y 20
pos 1 z 30
pos 1 time 1
pos 2 x 11
pos 2 y 22
pos 2 z 33
pos 2 time 2
pos 3 x 34
pos 3 y 45
pos 3 z 56
pos 3 time 3
见:
<>如果您真的想动态地考虑更多的列,则必须检测可用的列并动态创建和执行SQL语句。使用“纯”SQL无法做到这一点。第二次查询的成本高于第一次查询。我们可以使用透视表吗?我不知道交叉申请…可能会在12或18摄氏度?@OnkarTiwari。横向联接在Oracle 12+中。
POSITION COORD VALUE
-------- ----- -----
pos 1 x 10
pos 1 y 20
pos 1 z 30
pos 1 time 1
pos 2 x 11
pos 2 y 22
pos 2 z 33
pos 2 time 2
pos 3 x 34
pos 3 y 45
pos 3 z 56
pos 3 time 3