transpose column to row oracle

半腔热情 提交于 2019-12-01 01:21:38

In pure SQL, it will need a lot of coding because you will have to manually put the range as there is no relation between the values and the range at all. Had there been a relationship, you could use CASE expression and build the range dynamically.

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

From Oracle database 11g Release 1 and above, you could use 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

Above, in your case you need to replace the WITH clause with your existing query as a sub-query. You need to include other columns in the UNION.

In PL/SQL, you could (ab)use EXECUTE IMMEDIATE and get the "range" by extracting the column names in dynamic sql.

Although, it would be much better to modify/rewrite your existing query which you have not shown yet.

If you are using Oracle 11g version then you can use the UNPIVOT feature.

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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!