我有这种形式的查询返回值(查询返回超过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
在纯 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 并通过在 动态sql中 提取 列名称 来获取“范围” 。 *
虽然,修改/重写尚未显示的现有查询会更好。