行到列数据

row to column data

我有 table 名为 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 版本支持横向连接和 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

您可以使用简单的 UNPIVOT

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

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

Demo

您可以使用 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 语句。你不能用 "pure" SQL.