我在此表单中有一个查询返回值(查询返回超过50列)。
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 :(得分: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
上图中,您需要将现有查询中的 WITH 子句替换为子查询。您需要在 UNION 中包含其他列。
在 PL / SQL 中,您可以(ab)使用 EXECUTE IMMEDIATE 并通过提取列名来获取“范围” strong>动态sql 。
尽管如此,修改/重写您尚未显示的现有查询会好得多。
答案 1 :(得分: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'))