行到列数据

时间:2018-07-07 14:21:37

标签: 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 ;

给出期望的输出。但是我被告知这是不可行的查询。你们谁能为我提供最佳解决方案。

3 个答案:

答案 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)

您可以使用简单的UNPIVOT

SELECT
    col
FROM
    aa UNPIVOT ( col
        FOR val
    IN ( x,
         y,
         z ) );

我想您的面试官可能希望您回答这个问题?

Demo