6

我们有一个表格,其形式为:

ID,Value1,Value2,Value3
1,2,3,4

我们需要将其转化为。

ID,Name,Value
1,'Value1',2
1,'Value2',3
1,'Value3',4

在一个 SELECT 语句中(即没有 UNION)有没有一种聪明的方法?列名 Value1、Value2 和 Value3 是固定不变的。

数据库是oracle 9i。

4

9 回答 9

9

试一试union

select ID, 'Value1' as Name, Value1 as Value from table_name union all
select ID, 'Value2', Value2 as Value from table_name union all
select ID, 'Value3', Value3 as Value from table_name

order by ID, Name

usingunion all意味着服务器不会执行 a distinct(这在操作中是隐含的union)。它不应该对数据产生任何影响(因为您的 ID 应该完全不同),但它可能会加快速度。

于 2009-05-20T13:27:27.583 回答
4

这适用于 Oracle 10g:

select id, 'Value' || n as name,
       case n when 1 then value1 when 2 then value2 when 3 then value3 end as value
from (select rownum n
      from (select 1 from dual connect by level <= 3)) ofs, t

我认为 Oracle 9i 有递归查询?无论如何,我很确定它有 CASE 支持,所以即使它没有递归查询,您也可以执行“(select 1 from dual union all select 2 from dual union all select 3 from dual) ofs”代替。对 Oracle 来说,滥用递归查询更为普遍。(不过,使用联合生成行可以移植到其他数据库)

于 2009-05-20T14:03:16.607 回答
2

你可以这样做,但它并不漂亮:

SELECT id,'Value 1' AS name,value1 AS value FROM mytable
UNION
SELECT id,'Value 2' AS name,value2 AS value FROM mytable
UNION
SELECT id,'Value 3' AS name,value3 AS value FROM mytable
于 2009-05-20T13:27:42.357 回答
2

联合三个 select 语句应该可以解决问题:

SELECT ID, 'Value1', Value1 AS Value
FROM TABLE
UNION
SELECT ID, 'Value2', Value2 AS Value
FROM TABLE
UNION
SELECT ID, 'Value3', Value3 AS Value
FROM TABLE
于 2009-05-20T13:28:18.893 回答
0

如果您使用的是 SQL Server 2005+,那么您可以使用 UNPIVOT

CREATE TABLE #tmp ( ID int, Value1 int, Value2 int, Value3 int)

INSERT INTO #tmp (ID, Value1, Value2, Value3) VALUES (1, 2, 3, 4)

SELECT
    *
FROM
    #tmp

SELECT
    *
FROM
    #tmp
UNPIVOT
(
    [Value] FOR [Name] IN (Value1, Value2, Value3)
) uPIVOT

DROP TABLE #tmp
于 2009-05-20T13:29:56.050 回答
0

正如其他人所建议的那样,UNION ALL 可能是您在 SQL 中的最佳选择。您可能还需要考虑在前端处理此问题,具体取决于您的具体要求。

于 2009-05-20T14:14:20.890 回答
0

Oracle 的 CTE 语法可能不同(我在 Teradata 中运行它),但我只使用 CTE 提供测试数据,即 1 2 3 和 4。您可以使用临时表。实际的 select 语句是普通的普通 SQL,它适用于任何关系数据库。

于 2013-07-24T13:25:33.287 回答
-1

对于 Sql Server,考虑 UNPIVOT 作为 UNION 的替代方案:

SELECT id, value, colname
FROM #temp t
UNPIVOT (Value FOR ColName IN (value1,value2,value3)) as X

这也将返回列名。我不确定 X 的用途,但你不能忽略它。

于 2009-05-20T13:36:06.910 回答
-1

试试这个:

CTE 创建一个包含 4 个值的临时表。您可以在任何数据库中按原样运行它。

with TEST_CTE (ID) as

(select * from (select '1' as a) as aa  union all
select * from (select '2' as b) as bb  union all
select * from (select '3' as c) as cc  union all
select * from (select '4' as d) as dd )

select a.ID, 'Value'|| a.ID, b.ID
from TEST_CTE a, TEST_CTE b
where b.ID = (select min(c.ID) from TEST_CTE c where c.ID > a.ID)

这是结果集:

1   Value1  2

2   Value2  3

3   Value3  4

享受!

一些事后的想法。

^^^ CTE 语法在 Oracle 中可能不同。我只能在 Teradata 中运行它。您可以将其替换为临时表或修复语法以使其与 Oracle 兼容。select 语句是普通的普通 SQL,适用于任何数据库。

^^^ 还有一点要注意。如果 ID 字段是数字,您可能需要将其转换为 CHAR 以便将其与“值”连接起来。

于 2013-07-23T19:43:44.400 回答