我有一个名为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 ;
给出期望的输出。但是我被告知这是不可行的查询。你们谁能为我提供最佳解决方案。
答案 0 :(得分:3)
您的查询很好:
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的最新版本支持横向联接和apply
。如果您使用的是一个,我建议:
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
答案 1 :(得分:2)
您可以使用Oracle的UNPIVOT Clause
SELECT *
FROM AA
UNPIVOT (
value FOR name IN (x AS 'x', y AS 'y', z AS 'z')
);
会产生结果
name value
---- -----
x 10
y 20
z 30
请参阅:http://sqlfiddle.com/#!4/b274a/1/0
可以将其推广到更多列吗?由于需要事先知道列的名称,因此您不能使其自动考虑其他列,但是当然可以手动添加更多列。该示例还具有值列以外的其他列:
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
请参阅:http://sqlfiddle.com/#!4/47f5f/2/0
如果您真的想动态考虑更多列,则必须检测可用的列并动态创建和执行SQL语句。您无法使用“纯” SQL来做到这一点。
答案 2 :(得分:1)