2015-10-19 42 views
1

我有一个查询返回值在这种形式(查询返回超过50列)。转置列到行oracle

1-99transval 100-200transval 200-300transval ... 1-99nontransval 100... 
    50    90     80     67   58 

对于行值。我想这些细节将被转换成列,并采取以下形状:

Range  Transval  NonTransval 
1-99  50   67 
100-200  90   58 
+0

我很怀疑,你可以做到这一点没有动态生成并执行SQL,这意味着一个程序来驱动它。 – Turophile

+0

您是否需要输出中的所有范围,或仅显示两个范围? – Turophile

+0

我需要的所有范围 –

回答

4

在纯SQL,这将需要大量的编码,因为你将不得不手动将范围,因为没有值和范围之间的关系。如果存在关系,则可以使用CASE表达式并动态构建范围

SQL> WITH DATA AS 
    2 (SELECT 50 "1-99transval", 
    3  90 "100-200transval", 
    4  80 "200-300transval", 
    5  67 "1-99nontransval", 
    6  58 "100-200nontransval", 
    7  88 "200-300nontransval" 
    8 FROM dual 
    9 ) 
10 SELECT '1-99' range, 
11 "1-99transval" transval, 
12 "1-99nontransval" nontransval 
13 FROM DATA 
14 UNION 
15 SELECT '100-200' range, 
16 "100-200transval", 
17 "100-200nontransval" nontransval 
18 FROM DATA 
19 UNION 
20 SELECT '200-300' range, 
21 "200-300transval", 
22 "200-300nontransval" nontransval 
23 FROM DATA; 

RANGE  TRANSVAL NONTRANSVAL 
------- ---------- ----------- 
1-99   50   67 
100-200   90   58 
200-300   80   88 

Oracle数据库11g第1版以上,你可以使用UNPIVOT

SQL> WITH DATA AS 
    2 (SELECT 50 "1-99transval", 
    3  90 "100-200transval", 
    4  80 "200-300transval", 
    5  67 "1-99nontransval", 
    6  58 "100-200nontransval", 
    7  88 "200-300nontransval" 
    8 FROM dual 
    9 ) 
10 SELECT * 
11 FROM DATA 
12 UNPIVOT((transval,nontransval) 
13 FOR RANGE IN (("1-99transval","1-99nontransval") AS '1-99' 
14    ,("100-200transval","100-200nontransval") AS '100-200' 
15    ,("200-300transval","200-300nontransval") AS '200-300')); 

RANGE  TRANSVAL NONTRANSVAL 
------- ---------- ----------- 
1-99   50   67 
100-200   90   58 
200-300   80   88 

以上,你的情况,你需要与你现有的查询,以取代子句子查询。您需要在UNION中包含其他列。

PL/SQL,你可以(AB)使用EXECUTE 立即并通过动态SQL提取列名获得 “范围”。

虽然修改/重写您现有的尚未显示的查询会好很多。

4

如果您使用的是Oracle 11g版本,那么您可以使用UNPIVOT功能。

CREATE TABLE DATA AS 
SELECT 50 "1-99transval", 
    90 "100-200transval", 
    80 "200-300transval", 
    67 "1-99nontransval", 
    58 "100-200nontransval", 
    88 "200-300nontransval" 
    FROM dual 


SELECT * 
FROM DATA 
UNPIVOT((Transval,NonTransval) FOR Range IN (("1-99transval","1-99nontransval") as '1-99' 
              ,("100-200transval","100-200nontransval") as '100-200' 
              ,("200-300transval","200-300nontransval") as '200-300')) 

http://sqlfiddle.com/#!4/c9747/3/0