行到列数据
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 ) );
我猜你的面试官可能希望你回答这个问题?
您可以使用 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.
我有 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 ) );
我猜你的面试官可能希望你回答这个问题?
您可以使用 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.